0% found this document useful (0 votes)
18 views50 pages

UNIT-3 3.2 IWorking With Ansible

The document provides a comprehensive guide on setting up Ansible, including installation instructions for various Linux distributions and usage of ad-hoc commands for tasks such as file transfer, package management, and user management. It also covers the structure and creation of Ansible playbooks written in YAML, detailing how to define tasks and manage inventory. Additionally, it explains the concept of hosts and groups in Ansible inventory, along with examples of how to assign variables and manage configurations.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views50 pages

UNIT-3 3.2 IWorking With Ansible

The document provides a comprehensive guide on setting up Ansible, including installation instructions for various Linux distributions and usage of ad-hoc commands for tasks such as file transfer, package management, and user management. It also covers the structure and creation of Ansible playbooks written in YAML, detailing how to define tasks and manage inventory. Additionally, it explains the concept of hosts and groups in Ansible inventory, along with examples of how to assign variables and manage configurations.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 50

Setting up Ansible

Ansible Installation in Linux


• Once you have compared and weighed your options and decided to go
for Ansible, the next step is to have it installed on your system.
• We will go through the steps of installation in different Linux
distributions, the most popular ones, in the next small tutorial.

Install Ansible on Centos/RedHat systems


Step 1) Install EPEL repo

[root@ansible-server ~]# sudo yum install epel-release

Step 2) Install ansible package

[root@ansible-server ~]# sudo yum install -y ansible

Install ansible on Ubuntu/Debian systems


Step 1) Perform an update to the packages

$ sudo apt update

Step 2) Install the software-properties-common package

$ sudo apt install software-properties-common

Step 3) Install ansible personal package archive

$ sudo apt-add-repository ppa:ansible/ansible

Step 4) Install ansible


$ sudo apt update
$ sudo apt install ansible

Ansible ad-hoc Commands


• Ad-hoc commands are one of the simplest ways of using Ansible.
• These are used when you want to issue some commands on a server or
bunch of servers.
• The ad-hoc commands are not stored for future use, but it represents a
fast way to interact with the desired servers.
• The Ansible ad-hoc command uses the /usr/bin/ansible command-
line tool to automate a single task on one or more managed nodes.
• The Ad-hoc commands are quick and easy, but they are not re-usable.
• The Ad-hoc commands demonstrate the simplicity and power of
Ansible.
Syntax
ansible <hosts> [-m <module_name>] -a <"arguments"> -
u <username> [--become]
Explanation
• Hosts: It can be an entry in the inventory file. For specifying all hosts
in the inventory, use all or "*".
• module_name: It is an optional parameter. There are hundreds of
modules available in the Ansible, such as shell, yum, apt,
file, and copy. By default, it is the command.
• Arguments: We should pass values that are required by the module. It
can change according to the module used.
• Username: It specifies the user account in which Ansible can execute
commands.
• Become: It's an optional parameter specified when we want to run
operations that need sudo privilege. By default, it becomes false.
1. Parallelism and shell commands
• You can reboot your company server in 12 parallel forks at the same
time. For this, you need to set up the SSHagent for connection.
$ ssh-agent bash
$ ssh-add ~/.ssh/id_rsa
• To run reboot for all your company servers in the group, 'abc', in 12
parallel forks:
$ ansible abc -a "/sbin/reboot" -f 12
• By default, Ansible will run the above ad-hoc commands from the
current user account.
• If you want to change then pass the username in ad-hoc command as
follows:
$ ansible abc -a "/sbin/reboot" -f 12 -u username
2. File Transfer
• You can use ad-hoc commands for doing SCP (secure copy protocol)
which means lots of files in parallel on multiple machines or servers.
Transferring file on many machines or servers
$ ansible abc -m copy -a "src = /etc/yum.conf dest = /tmp/yum.conf"
Creating new directory
$ ansible abc -m file -
a "dest = /path/user1/new mode = 888 owner = user1 group = user1
state = directory"
Deleting all directory and files
$ ansible abc -m file -a "dest = /path/user1/new state = absent"
3. Managing Packages
• Ad-hoc commands are available for apt and yum module.
• Here are the following ad-hoc commands using yum.
• Below command checks, if the yum package is installed or not, but not
update it.
$ ansible abc -m yum -a "name = demo-tomcat-1 state = present"
• Below command checks the package is not installed.
$ ansible abc -m yum -a "name = demo-tomcat-1 state = absent"
• And below command checks the latest version of package is installed.
$ ansible abc -m yum -a "name = demo-tomcat-1 state = latest"
4. Managing Users and Groups
• You can manage, create, and remove a user account on your managed
nodes with ad-hoc commands.
$ ansible all -m user -a "name=foo password=
<crypted password here>"
$ ansible all -m user -a "name=foo state=absent"
5. Managing Services
• Ensure a service is started on all the webservers.
$ ansible webservers -m service -a "name=httpd state=started"
• Alternatively, restart a service on all webservers:
$ ansible webservers -m service -a "name=httpd state=restarted"
• Ensure a service is stopped:
$ ansible webservers -m service -a "name=httpd state=stopped"
6. Gathering Facts
• Fact represents the discovered variables about a system.
• You can use the facts to implement conditional execution of tasks, and
also used to get ad-hoc information about your systems.
• To see all the facts:
$ ansible all -m setup

Ansible Playbooks
• Playbooks are the files where the Ansible code is written.
• Playbooks are written in YAML format.
• YAML means "Yet Another Markup Language," so there is not much
syntax needed.
• Playbooks are one of the core features of Ansible and tell Ansible what
to execute, and it is used in complex scenarios.
• They offer increased flexibility.
• Playbooks contain the steps which the user wants to execute on a
particular machine.
• And playbooks are run sequentially.
• Playbooks are the building blocks for all the use cases of Ansible.
• Ansible playbooks tend to be more configuration language than a
programming language.
• Through a playbook, you can designate specific roles to some of the
hosts and other roles to other hosts.
• By doing this, you can orchestrate multiple servers in very different
scenarios, all in one playbook.
Playbook Structure
• Each playbook is a collection of one or more plays.
• Playbooks are structured by using Plays.
• There can be more than one play inside a playbook.

• The function of the play is to map a set of instructions which is defined


against a particular host.
• There are different YAML editors, but prefer to use a simple editor
such as notepad++.
• First, open the notepad++ and copy-paste the below YAML and
change the language to YAML (Language → YAML).
• A YAML starts with --- (3 hyphens) always.
Create a Playbook
• Let's start by writing an example YAML file.
• First, we must define a task.
• These are the interface to ansible modules for roles and playbooks.
• One playbook with one play, containing multiple tasks looks like the
below example.
---
name: install and configure DB
hosts: testServer
become: yes

vars:
oracle_db_port_value : 1521

tasks:
-name: Install the Oracle DB
yum: <code to install the DB>

-name: Ensure the installed service is enabled and running


service:
name: <your service name>
• Above is a basic syntax of a playbook. Save it in a file as test.yml.
• A YAML syntax needs to follow the correct indentation.
• YAML Tags
• Here are some YAML tags are given below, such as:
Name It specifies the name of the Ansible Playbooks.

Hosts It specifies the lists of the hosts against which you want to run
the task. And the host's Tag is mandatory. It tells Ansible that
on which hosts to run the listed tasks. These tasks can be run on
the same machine or the remote machine. One can run the tasks
on the multiple machines, and the host's tag can have a group
of host's entry as well.

Vars Vars tag defines the variables which you can use in your
playbook. Its usage is similar to the variables in any
programming language.
Tasks Tasks are the lists of the actions which need to perform in the
playbooks. All the playbooks should contain the tasks to be
executed. A task field includes the name of the task. It is not
mandatory but useful for debugging the playbook. Internally
each task links to a piece of code called a module. A module
should be executed, and arguments that are required for the
module you want to run.

Ansible YAML
• YAML is used to describe configuration that has been increasing in the
past few years with the help of Ansible and SaltStack.
• YAML is more comfortable for humans to read and write in
comparison to other standard data formats such as XML or JSON.
• There are libraries available in most programming languages for
working with YAML.
• For Ansible, every YAML file starts with a list.
• Each item in the list is a list of key-value pairs, commonly called
a "hash" or "dictionary".
• So, we need to know how to write lists and dictionaries in YAML.
• There’s another small quirk to YAML.
• All YAML files (regardless of their association with Ansible or not)
can optionally begin with --- and end with ---.
• This is part of the YAML format and indicates the start and end of a
document.
• All members of a list are lines beginning at the same indentation level
starting with a "-" (a dash and space):
---
# A list of colors
- White
- Orange
- Red
- Black
---
• We have different ways in which the YAML data is represented, such
as:
Key-value Pair
• YAML uses the Key-Value pair to represent the data.
• And the dictionary is described in the key: value pair.
NOTE: There should be space between: and value.
For example, a student record
---
# A student record
Martin:
name: Martin
roll no: 10
class: 12th
div: A
---
Abbreviation
• We can also use the abbreviation to represent the directories:
Martin: [name: martin, roll no: 10, class: 12th, div: A]
Representing List
• We can also represent List in YAML.
• Every element (member) of the list should be written in a new line with
the same indentation starting with "-" (- and space).
For example: Name of the countries
---
#Name of country
Countries:
- India
- China
- USA
- Iceland
---
Abbreviation
• To represent the list, we can also use the abbreviation method:
Countries: ['India', 'China', 'USA', 'Iceland']
List inside Dictionaries
• We can use the list inside dictionaries, i.e., the value of a key is a list.
For example, a student record
---
# A student record
Martin:
name: Martin
roll no: 10
class: 12th
div: A
likes:
- Physics
- Chemistry
- Math
---
List of Directories
• We can also make a list of directories:
For example:
---
# A student record
- Martin:
name: Martin
roll no: 10
class: 12th
div: A
likes:
- Physics
- Chemistry
- Math
- Edward:
name: Edward
roll no: 11
class: 12th
div: A
likes:
- Biology
- English
---
• YAML uses "|" to include newlines while showing multiple lines
and ">" to suppress newlines while showing various lines.
• Due to this, we can read and edit long lines.
• In both cases, the indentation will be ignored.
• We can also represent Boolean (True/false) values in YAML,
where Boolean values can be case insensitive.
For example, a student result
---
#a student result
- Martin:
name: Martin
roll no: 10
class: 12th
div: A
likes:
- Physics
- Chemistry
- Math

result:
Physics: 70
Chemistry: 45
Math: 85
Biology: 65
English: 80

passed: TRUE

messageIncludeNewLines: |
Congratulation!!
You passed with 79%

messageExcludeNewLines: >
Congratulation!!
You passed with 79%
---
Ansible Inventory
• Ansible works against multiple managed hosts in your infrastructure at
the same time, using a list or group of lists is known as the inventory.
• Once an inventory is defined, you use patterns to select the hosts or
groups you want to run against to Ansible.
• The default location for inventory is a file called /etc/ansible/hosts.
You can also specify a different inventory file at the command line
using the -i <path> option.
• You can pull the inventory file from dynamic or cloud sources or
different formats (YAML, ini).
• Ansible has inventory plugins to make it flexible and customize.

Hosts and group


• The format is /etc/ansible/ hosts are in INI like format, such as:
mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com
• Heading in the brackets is a group name, which is used in classifying
the systems.
• And deciding what policy you are controlling at what time and for
what purpose.
• You can put the systems in more than one group.
• For example, a server could be both a dbserver and a webserver.
• If you have hosts that run on a non-standard SSH port, then you can
put the port number after the hostname with the colon.
• The Ports listed in the SSH configuration file that can be used with
the OpenSSH connection but not use with
the paramiko connection.
• To makes things explicit, it is suggested that you set them if items
are not running on the default ports:
badwolf.example.com:5309
• Suppose you have static IPs and want to set up some aliases that live
in your host file, or you can connect through tunnels.
• Also, you can describe the hosts like the below example:
Jumper ansible_port=5555 ansible_host=192.0.2.50
• In the above example, trying to Ansible against the host alias
"jumper" will connect 192.0.2.50 on port 5555.
• It is using features of the inventory file to define the special
variables.

Hosts Variables
• You can assign the variables to the hosts that will be used in
playbooks, such as:
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909

Group Variables
• The variables can be applied to an entire group at once, such as:
[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
Groups of Groups and Group Variables
• It is possible to make groups of the group using the :children's suffix.
And you can apply variables using :vars.
[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast: children]
Atlanta
Raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa: children]
southeast
northeast
southwest
northwest

Step to install Python using ansible-playbook


Step 1: Launch an instance
• Go to Amazon console management and log into that with your
credentials or create a New account.
• Now launch two Instances because Ansible is a master-slave
configuration management tool.
• So We are working from the master node and installing Python in
the slave node.
• In the master node, we are defining the host details of the slave node.

• Now connect with terminal like git bash, powershell, putty,


command prompt and so on.
• By using SSH Command

Step 2: Install Ansible


• Now Install Ansible on your control node (local machine). By using
following command
sudo amazon-linux-extras install ansible2
Step 3: Create a playbook
• Now create a playbook with .yml extension
sudo vi <filename.yml>
• Here is the playbook script to install PYTHON in slave node
- name: Install Python
hosts: slave # here give your instance name
become: yes
tasks:
- name: Install Python
package:
name: python
state: present

Step 4: Setting up Host Permission for slave node


• Now move to ansible directory path.
• In that ansible directory there is a file for HOST. In that host file we
can provide host details.
• Following command navigate to ansible path
cd /etc/ansible/
• Now open that Host file by using following command. Without sudo
we cannot open that file
sudo vi host

• Inside this host file we providing host details that means our slave
node details like Private IP Address, user name and keypairs details
because to install our python.
• Ensure that our instance keypair's was downloaded in local machine
that is our master node. We can download by using following
command
scp -i keyapir.pem keypair.pem ec2-user@public-IP-
address:/home/ec2-user(path to download)
• After that change permissions to that keypair file because security
purpose only giving read permissions. By using following command
sudo chmod 400 <keypair.pem>

• Now execute ansible ping command to verify that our slave node
connected or not
ansible ping -m all
Step 5: Running the Playbook
• Now run ansible-playbook command to run your playbook,
specifying the playbook file and target hosts.
• By using following command
ansible-playbook <filename.yml>

• To verify whether python installed or not by using following


command.
• Check in slave node because we installed in slave node.
python --version
Ansible Roles
• Ansible is a powerful open-source automation tool and after its origin,
it has made the management of system administration very simple and
effective.
• One of Ansible's main features is its use of roles which adds structure
and reusability to configuration management.
• Ansible roles made their debut in version 1.2, aiming to solve the
challenges associated with managing complex configurations.
• The introduction of roles offered a solution by providing a modular
and organized approach to configuration management.

How to Use Ansible Roles:


1. Directory Structure
• Ansible roles follow a structured directory format to organize tasks,
variables, and other components.
• When creating a role, you'll typically have directories like tasks, vars,
templates, and meta.
• This structure helps keep your configurations modular and easy to
navigate.
2. Writing Tasks
• Tasks form the foundation of Ansible roles.
• In the tasks/main.yml file within the role directory, you define what
actions need to be performed.
• These actions can range from installing packages and configuring
files to managing services.
• Tasks are like the step-by-step instructions for Ansible to follow
when applying for the role.
3. Defining Variables
• Variables are used for customization and flexibility within Ansible
roles.
• The vars directory within a role is where you can define specific
variables applicable to that role.
• Variables make your roles adaptable to different environments or
configurations without modifying the role itself.
4. Handling Templates
• For dynamic configuration files, Ansible uses the templates directory
within a role.
• Templates allow you to create configuration files that can be
customized based on variables.
• This dynamic approach ensures that roles can be versatile and handle
various scenarios.
5. Including Roles in Playbooks
• To apply roles within playbooks, you use the roles keyword.
• Specify the roles to be applied, and Ansible will automatically
execute the tasks defined within each role.
• This makes it easy to reuse roles across different playbooks and
ensures consistency in configurations.
What are System Roles
• Ansible also provides system roles—pre-built roles that address
common system administration tasks.
• These roles are designed to simplify the management of specific
aspects of a system.
• Let's explore a couple of examples:
1. Ansible.Builtin.Users Role
This role simplifies user management on Linux systems. It allows you to
create or remove users, set passwords, and manage user attributes.
Example usage in a playbook:
- hosts: servers
roles:
- ansible.builtin.users
vars:
users:
- username: john
groups: sudo
password: "{{ 'secure_password' | password_hash('sha512') }}"
state: present
This example creates a user named 'john,' adds them to the 'sudo' group,
sets a secure password, and ensures the user is present.
2. Ansible.Builtin.Firewalld Role
For managing firewalls, Ansible provides the ansible.builtin.firewalld
role. It simplifies the configuration of the firewalld service on Linux
systems.
Example usage in a playbook:
- hosts: servers
roles:
- ansible.builtin.firewalld
vars:
firewalld_services:
- service: http
zone: public
state: enabled
This example enables the HTTP service in the public zone using the
firewalld role.

Creating a New Role


• The directory structure for roles is essential to create a new role.

Role Structure
• Roles have a structured layout on the file system.
• The default structure can be changed but for now let us stick to defaults.
• Each role is a directory tree in itself.
• The role name is the directory name within the /roles directory.
$ ansible-galaxy -h
Usage
ansible-galaxy
[delete|import|info|init|install|list|login|remove|search|setup] [--help]
[options] ...
Options
• -h, --help − Show this help message and exit.
• -v, --verbose − Verbose mode (-vvv for more, -vvvv to
enable connection debugging)
• --version − Show program's version number and exit.
Creating a Role Directory
• The above command has created the role directories.
$ ansible-galaxy init vivekrole
ERROR! The API server (https://galaxy.ansible.com/api/) is not
responding, please try again later.

$ ansible-galaxy init --force --offline vivekrole


- vivekrole was created successfully

$ tree vivekrole/
vivekrole/
defaults
main.yml
files handlers
main.yml
meta
main.yml
README.md tasks
main.yml
templates tests inventory
test.yml
vars
main.yml

8 directories, 8 files
• Not all the directories will be used in the example and we will show
the use of some of them in the example.

Utilizing Roles in Playbook


• This is the code of the playbook we have written for demo
purpose.
• This code is of the playbook vivek_orchestrate.yml.
• We have defined the hosts: tomcat-node and called the two
roles install-tomcat and start-tomcat.
• The problem statement is that we have a war which we need to
deploy on a machine via Ansible.
---
- hosts: tomcat-node
roles:
- {role: install-tomcat}
- {role: start-tomcat}
• Contents of our directory structure from where we are running
the playbook.

$ ls
• ansible.cfg hosts roles vivek_orchestrate.retry vivek_orchestrate.yml

• There is a tasks directory under each directory and it contains a


main.yml. The main.yml contents of install-tomcat are −
---
#Install vivek artifacts
-
block:
- name: Install Tomcat artifacts
action: >
yum name = "demo-tomcat-1" state = present
register: Output
always:
- debug:
msg:
- "Install Tomcat artifacts task ended with message: {{Output}}"
- "Installed Tomcat artifacts - {{Output.changed}}"
• The contents of main.yml of the start tomcat are −
#Start Tomcat
-
block:
- name: Start Tomcat
command: <path of tomcat>/bin/startup.sh"
register: output
become: true

always:
- debug:
msg:
- "Start Tomcat task ended with message: {{output}}"
- "Tomcat started - {{output.changed}}"
• The advantage of breaking the playbook into roles is that anyone who
wants to use the Install tomcat feature can call the Install Tomcat role.

Breaking a Playbook into a Role


• If not for the roles, the content of the main.yml of the respective role
can be copied in the playbook yml file.
• But to have modularity, roles were created.
• Any logical entity which can be reused as a reusable function, that
entity can be moved to role.
• The example for this is shown above
• Ran the command to run the playbook.
-vvv option for verbose output verbose output
$ cd vivek-playbook/
• This is the command to run the playbook
$ sudo ansible-playbook -i hosts vivek_orchestrate.yml vvv
-----------------------------------------------------------------
-----------------------------------------------------------------------
Output
• The generated output is as seen on the screen −
• Using /users/demo/vivek-playbook/ansible.cfg as config file.
PLAYBOOK: vivek_orchestrate.yml
*********************************************************
**********************************************************
*
1 plays in vivek_orchestrate.yml

PLAY [tomcat-node]
**********************************************************
************
******** *************************************************

TASK [Gathering Facts]


*************************************************
******************************
*********************************************
Tuesday 21 November 2017 13:02:05 +0530 (0:00:00.056)
0:00:00.056 ******
Using module file
/usr/lib/python2.7/sitepackages/ansible/modules/system/setup.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249525.88-259535494116870 `"
&&
echo ansible-tmp-1511249525.88-259535494116870="`
echo /root/.ansible/tmp/ansibletmp-1511249525.88-
259535494116870 `" ) && sleep 0'
<localhost> PUT /tmp/tmpPEPrkd TO
/root/.ansible/tmp/ansible-tmp-
1511249525.88259535494116870/setup.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/
/root/.ansible/tmp/ansible-tmp-
1511249525.88259535494116870/setup.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249525.88-
259535494116870/setup.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/" >
/dev/null 2>&1 && sleep 0'
ok: [server1]
META: ran handlers

TASK [install-tomcat : Install Tomcat artifacts]


***********************************
**********************************************************
*****
task path: /users/demo/vivek-playbook/roles/install-
tomcat/tasks/main.yml:5
Tuesday 21 November 2017 13:02:07 +0530 (0:00:01.515)
0:00:01.572 ******
Using module file
/usr/lib/python2.7/sitepackages/ansible/modules/packaging/os/yum.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249527.34-40247177825302 `"
&& echo
ansibletmp-1511249527.34-40247177825302="` echo
/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302 `" )
&& sleep 0'
<localhost> PUT /tmp/tmpu83chg TO
/root/.ansible/tmp/ansible-tmp-
1511249527.3440247177825302/yum.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/
/root/.ansible/tmp/ansible-tmp-
1511249527.3440247177825302/yum.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249527.34-
40247177825302/yum.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/" >
/dev/null 2>
&1 && sleep 0'
changed: [server1] => {
"changed": true,
"invocation": {
"module_args": {
"conf_file": null,
"disable_gpg_check": false,
"disablerepo": null,
"enablerepo": null,
"exclude": null,
"install_repoquery": true,
"installroot": "/",
"list": null,
"name": ["demo-tomcat-1"],
"skip_broken": false,
"state": "present",
"update_cache": false,
"validate_certs": true
}
},
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: product-id,
search-disabled-repos,
subscriptionmanager\nThis system is not registered to Red Hat
Subscription Management.
You can use subscription-manager to register.\nResolving
Dependencies\n-->
Running transaction check\n--->
Package demo-tomcat-1.noarch 0:SNAPSHOT-1 will be installed\n-
-> Finished Dependency
Resolution\n\nDependencies Resolved\n

\n=========================================
=======================================\n
Package Arch Version Repository

Size\n=======================================
===========================\nInstalling:\n
demo-tomcat-1 noarch SNAPSHOT-1 demo-repo1 7.1
M\n\nTransaction

Summary\n====================================
==============================\nInstall 1
Package\n\nTotal download size: 7.1 M\nInstalled size: 7.9
M\nDownloading
packages:\nRunning transaction
check\nRunning transaction test\nTransaction test
succeeded\nRunning transaction\n Installing :
demotomcat-1-SNAPSHOT-1.noarch 1/1 \n Verifying :
demo-tomcat-1-SNAPSHOT-1.noarch 1/1 \n\nInstalled:\n
demo-tomcat-1.noarch 0:SNAPSHOT-1 \n\nComplete!\n"
]
}

TASK [install-tomcat : debug]


**********************************************************
**********************************************************
*****************
task path: /users/demo/vivek-playbook/roles/install-
tomcat/tasks/main.yml:11
Tuesday 21 November 2017 13:02:13 +0530 (0:00:06.757)
0:00:08.329 ******
ok: [server1] => {
"changed": false,
"msg": [
"Install Tomcat artifacts task ended with message: {
u'msg': u'', u'changed': True, u'results':
[u'Loaded plugins: product-id,
search-disabledrepos,
subscription-manager\\nThis system is not registered to Red Hat
Subscription Management.
You can use subscription-manager to register.\\nResolving
Dependencies\\n-->
Running transaction check\\n--->
Package demo-tomcat-1.noarch 0:SNAPSHOT-1 will be
installed\\n-->
Finished Dependency Resolution\\n
\\nDependencies

Resolved\\n\\n==================================
================================\\n
Package Arch Version Repository
Size\\n=======================================
=================================
=====\\nInstalling:\\n demo-tomcat-1 noarch SNAPSHOT-1
demo-repo1 7.1 M\\n\\nTransaction

Summary\\n===================================
======================\\nInstall 1
Package\\n\\nTotal download size: 7.1 M\\nInstalled size: 7.9
M\\nDownloading
packages:\\nRunning
transaction check\\nRunning transaction test\\nTransaction test
succeeded\\nRunning
transaction\\n
Installing : demo-tomcat-1-SNAPSHOT-1.noarch 1/1 \\n
Verifying :
demo-tomcat-1-SNAPSHOT-1.noarch
1/1 \\n\\nInstalled:\\n demo-tomcat-1.noarch 0:SNAPSHOT-1
\\n\\nComplete!\\n'], u'rc': 0
}",
"Installed Tomcat artifacts - True"
]
}

TASK [install-tomcat : Clean DEMO environment]


****************************************
**********************************************************
**
task path: /users/demo/vivek-playbook/roles/install-
tomcat/tasks/main.yml:19
Tuesday 21 November 2017 13:02:13 +0530 (0:00:00.057)
0:00:08.387 ******
[WARNING]: when statements should not include jinja2 templating
delimiters such as {{ }} or
{% %}. Found: {{installationOutput.changed}}

Using module file


/usr/lib/python2.7/sitepackages/ansible/modules/files/file.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.13-128345805983963 `"
&& echo
ansible-tmp-1511249534.13-128345805983963="` echo
/root/.ansible/tmp/ansibletmp-1511249534.13-128345805983963 `" )
&& sleep 0'
<localhost> PUT /tmp/tmp0aXel7 TO
/root/.ansible/tmp/ansible-tmp-
1511249534.13128345805983963/file.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/
/root/.ansible/tmp/ansible-tmp-
1511249534.13128345805983963/file.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.13-
128345805983963/file.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/" >
/dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"diff": {
"after": {
"path": "/users/demo/DEMO",
"state": "absent"
},
"before": {
"path": "/users/demo/DEMO",
"state": "directory"
}
},

"invocation": {
"module_args": {
"attributes": null,
"backup": null,
"content": null,
"delimiter": null,
"diff_peek": null,
"directory_mode": null,
"follow": false,
"force": false,
"group": null,
"mode": null,
"original_basename": null,
"owner": null,
"path": "/users/demo/DEMO",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "absent",
"unsafe_writes": null,
"validate": null
}
},
"path": "/users/demo/DEMO",
"state": "absent"
}

TASK [install-tomcat : debug]


********************************************************
**********************************************************
***
task path: /users/demo/vivek-playbook/roles/install-
tomcat/tasks/main.yml:29
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.257)
0:00:08.645 ******
ok: [server1] => {
"changed": false,
"msg": [
"Clean DEMO environment task ended with message:{u'diff':
{u'after': {u'path':
u'/users/demo/DEMO', u'state': u'absent'},
u'before': {u'path': u'/users/demo/DEMO', u'state': u'directory'}},
u'state': u'absent',
u'changed': True, u'path': u'/users/demo/DEMO'}",
"check value :True"
]
}

TASK [install-tomcat : Copy Tomcat to user home]


*************************************
********************************************************
task path: /users/demo/vivek-playbook/roles/install-
tomcat/tasks/main.yml:37
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.055)
0:00:08.701 ******
[WARNING]: when statements should not include jinja2 templating
delimiters such as {{ }} or
{% %}. Found: {{installationOutput.changed}}

Using module file


/usr/lib/python2.7/sitepackages/ansible/modules/commands/command.p
y
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.43-41077200718443 `"
&& echo
ansibletmp-1511249534.43-41077200718443="` echo
/root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443 `" )
&& sleep 0'
<localhost> PUT /tmp/tmp25deWs TO
/root/.ansible/tmp/ansible-tmp-
1511249534.4341077200718443/command.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443/
/root/.ansible/tmp/ansible-tmp-
1511249534.4341077200718443/command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.43-
41077200718443/command.py; rm -rf
"/root/.ansible/tmp/ansibletmp-1511249534.43-41077200718443/" >
/dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"cmd": [
"cp",
"-r",
"/opt/ansible/tomcat/demo",
"/users/demo/DEMO/"
],
"delta": "0:00:00.017923",
"end": "2017-11-21 13:02:14.547633",
"invocation": {
"module_args": {
"_raw_params": "cp -r /opt/ansible/tomcat/demo
/users/demo/DEMO/",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
}
},
"rc": 0,
"start": "2017-11-21 13:02:14.529710",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}

TASK [install-tomcat : debug]


********************************************************
**********************************************************
task path: /users/demo/vivek-playbook/roles/install-
tomcat/tasks/main.yml:47
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.260)
0:00:08.961 ******
ok: [server1] => {
"changed": false,
"msg": "Copy Tomcat to user home task ended with message {
'stderr_lines': [], u'changed': True, u'end': u'2017-11-21
13:02:14.547633', u'stdout':
u'', u'cmd': [u'cp', u'-r', u'/opt/ansible/tomcat/demo',
u'/users/demo/DEMO/'], u'rc': 0,
u'start': u'2017-11-21 13:02:14.529710', u'stderr': u'', u'delta':
u'0:00:00.017923',
'stdout_lines': []}"
}

TASK [start-tomcat : Start Tomcat]


**************************************************
**********************************************************
task path: /users/demo/vivek-playbook/roles/start-
tomcat/tasks/main.yml:5
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.044)
0:00:09.006 ******
Using module file
/usr/lib/python2.7/sitepackages/ansible/modules/commands/command.p
y
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.63-46501211251197 `"
&& echo
ansibletmp-1511249534.63-46501211251197="` echo
/root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197 `" )
&& sleep 0'
<localhost> PUT /tmp/tmp9f06MQ TO
/root/.ansible/tmp/ansible-tmp-
1511249534.6346501211251197/command.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197/
/root/.ansible/tmp/ansible-tmp-
1511249534.6346501211251197/command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.63-
46501211251197/command.py; rm -rf
"/root/.ansible/tmp/ansibletmp-1511249534.63-46501211251197/" >
/dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"cmd": [ "/users/demo/DEMO/bin/startup.sh" ],
"delta": "0:00:00.020024",
"end": "2017-11-21 13:02:14.741649",
"invocation": {
"module_args": {
"_raw_params": "/users/demo/DEMO/bin/startup.sh",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
}
},
"rc": 0,
"start": "2017-11-21 13:02:14.721625",
"stderr": "",
"stderr_lines": [],
"stdout": "Tomcat started.",
"stdout_lines": [ "Tomcat started." ]
}

TASK [start-tomcat : debug]


*************************************************
**********************************************************
************
task path: /users/demo/vivek-playbook/roles/start-
tomcat/tasks/main.yml:10
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.150)
0:00:09.156 ******
ok: [server1] => {
"changed": false,
"msg": [
"Start Tomcat task ended with message: {'
stderr_lines': [], u'changed': True, u'end': u'2017-11-21
13:02:14.741649', u'stdout':
u'Tomcat started.', u'cmd': [u'/users/demo/DEMO/bin/startup.sh'],
u'rc': 0, u'start':
u'2017-11-21 13:02:14.721625', u'stderr': u'', u'delta':
u'0:00:00.020024',
'stdout_lines': [u'Tomcat started.']}",
"Tomcat started - True"
]
}
META: ran handlers
META: ran handlers
PLAY RECAP
**********************************************************
*********************
*********************************************************
server1 : ok = 9 changed = 4 unreachable = 0 failed = 0

Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.042)


0:00:09.198 ******
===========================================
====================================
install-tomcat : Install Tomcat artifacts ------------------------------- 6.76s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:5 -------
-------
Gathering Facts --------------------------------------------------------- 1.52s
------------------------------------------------------------------------------
install-tomcat : Copy Tomcat to user home -------------------------------
0.26s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:37 -----
--------

install-tomcat : Clean DEMO environment ---------------------------------


0.26s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:19 -----
--------

start-tomcat : Start Tomcat --------------------------------------------- 0.15s


/users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:5 ---------
-------

install-tomcat : debug -------------------------------------------------- 0.06s


/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:11 -----
--------

install-tomcat : debug -------------------------------------------------- 0.06s


/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:29 -----
--------

install-tomcat : debug -------------------------------------------------- 0.04s


/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:47 -----
--------

start-tomcat : debug ---------------------------------------------------- 0.04s


/users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:10 -------
--------

• Hit the following URL and you will be directed to a page as


shown below
− http://10.76.0.134:11677/HelloWorld/HelloWorld

• The deployed war just has a servlet which displays Hello World.
• The detailed output shows the time taken by each and every task
because of the entry added in ansible.cfg file −
[defaults]
callback_whitelist = profile_tasks
Creating Ansible Roles
• To create a Ansible roles, use ansible-galaxy command which has the
templates to create it.
• This will create it under the default directory /etc/ansible/roles and do
the modifications else we need to create each directories and files
manually.
[root@learnitguide ~]# ansible-galaxy init /etc/ansible/roles/apache
--offline
- apache was created successfully
[root@learnitguide ~]#
• where, ansible-glaxy is the command to create the roles using the
templates.
init is to initiliaze the role.
apache is the name of role,
offline - create offline mode rather than getting from online
repository.

List out the directory created under /etc/ansible/roles.

[root@learnitguide ~]# tree /etc/ansible/roles/apache/


/etc/ansible/roles/apache/
|-- README.md
|-- defaults
| `-- main.yml
|-- files
|-- handlers
| `-- main.yml
|-- meta
| `-- main.yml
|-- tasks
| `-- main.yml
|-- templates
|-- tests
| |-- inventory
| `-- test.yml
`-- vars
`-- main.yml
8 directories, 8 files
[root@learnitguide ~]#
• We have got the clean directory structure with the ansible-galaxy
command.
• Each directory must contain a main.yml file, which contains the
relevant content.

Directory Structure:
• tasks - contains the main list of tasks to be executed by the role.
• handlers - contains handlers, which may be used by this role or even
anywhere outside this role.
• defaults - default variables for the role.
• vars - other variables for the role. Vars has the higher priority than
defaults.
• files - contains files required to transfer or deployed to the target
machines via this role.
• templates - contains templates which can be deployed via this role.
• meta - defines some data / information about this role (author,
dependency, versions, examples, etc,.)
• Lets take an example to create a role for Apache Web server.
• Below is a sample playbook codes to deploy Apache web server. Lets
convert this playbook codes into Ansible roles.
---
- hosts: all
tasks:
- name: Install httpd Package
yum: name=httpd state=latest
- name: Copy httpd configuration file
copy: src=/https/www.scribd.com/data/httpd.original dest=/etc/httpd/conf/httpd.conf
- name: Copy index.html file
copy: src=/https/www.scribd.com/data/index.html dest=/var/www/html
notify:
- restart apache
- name: Start and Enable httpd service
service: name=httpd state=restarted enabled=yes
handlers:
- name: restart apache
service: name=httpd state=restarted
• First, move on to the Ansible roles directory and start editing the yml
files.
cd /etc/ansible/roles/apache

1. Tasks
• Edit main.yml available in the tasks folder to define the tasks to be
executed.
[root@learnitguide apache]# vi tasks/main.yml
---
- name: Install httpd Package
yum: name=httpd state=latest
- name: Copy httpd configuration file
copy: src=/https/www.scribd.com/data/httpd.original dest=/etc/httpd/conf/httpd.conf
- name: Copy index.html file
copy: src=/https/www.scribd.com/data/index.html dest=/var/www/html
notify:
- restart apache
- name: Start and Enable httpd service
service: name=httpd state=restarted enabled=yes
• Altogether, you can add all your tasks in this file or just break the codes
even more as below using "import_tasks" statements.

[root@learnitguide apache]# cat tasks/main.yml


---
# tasks file for /etc/ansible/roles/apache
- import_tasks: install.yml
- import_tasks: configure.yml
- import_tasks: service.yml

• Lets create install.yml, confgure.yml, service.yml included in the


main.yml with actions in the same directory.
install.yml
[root@learnitguide apache]# cat tasks/install.yml
---
- name: Install httpd Package
yum: name=httpd state=latest

configure.yml

[root@learnitguide apache]# cat tasks/configure.yml


---
- name: Copy httpd configuration file
copy: src=files/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: Copy index.html file
copy: src=files/index.html dest=/var/www/html
notify:
- restart apache
service.yml
[root@learnitguide apache]# cat tasks/service.yml
---
- name: Start and Enable httpd service
service: name=httpd state=restarted enabled=yes

2. Files
Copy the required files (httpd.conf and index.html) to the files directory.

[root@learnitguide apache]# ll files/*


-rw-r--r-- 1 root root 11753 Feb 4 10:01 files/httpd.conf
-rw-r--r-- 1 root root 66 Feb 4 10:02 files/index.html
[root@learnitguide apache]# cat files/index.html
This is a homepage created by learnitguide.net for ansible roles.
[root@learnitguide apache]#

3. Handlers

Edit handlers main.yml to restart the server when there is a change.


Because we have already defined it in the tasks with notify option. Use
the same name "restart apache" within the main.yml file as below.

[root@learnitguide apache]# cat handlers/main.yml


---
# handlers file for /etc/ansible/roles/apache
- name: restart apache
service: name=httpd state=restarted

4. Meta
Edit meta main.yml to add the information about the roles like author,
descriptions, license, platforms supported.
[root@learnitguide apache]# cat meta/main.yml
galaxy_info:
author: LearnItGuide.net
description: Apache Webserver Role
company: LearnITGuide.net
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Some suggested licenses:
# - BSD (default)
# - MIT
# - GPLv2
# - GPLv3
# - Apache
# - CC-BY
license: license (GPLv2, CC-BY, etc)
min_ansible_version: 1.2
# If this a Container Enabled role, provide the minimum Ansible
Container version.
------skipped

List out the created files now,

[root@learnitguide apache]# tree


.
|-- README.md
|-- defaults
| `-- main.yml
|-- files
| |-- httpd.conf
| `-- index.html
|-- handlers
| `-- main.yml
|-- meta
| `-- main.yml
|-- tasks
| |-- configure.yml
| |-- install.yml
| |-- main.yml
| `-- service.yml
|-- templates
|-- tests
| |-- inventory
| `-- test.yml
`-- vars
`-- main.yml
8 directories, 13 files
[root@learnitguide apache]#

We have got all the required files for Apache roles. Lets apply this role
into the ansible playbook "runsetup.yml" as below to deploy it on the
client nodes.

[root@learnitguide apache]# cat /etc/ansible/runsetup.yml


---
- hosts: node2
roles:
- apache
[root@learnitguide apache]#

We have defined this changes should be run only on node2, you can also
use "all" if need. Specify the role name as "apache", also if you have
created multiple roles, you can use the below format to add it.
- apache
- nfs
- ntp

Lets verify for syntax errors:

[root@learnitguide apache]# ansible-playbook


/etc/ansible/runsetup.yml --syntax-check
playbook: /etc/ansible/runsetup.yml
[root@learnitguide apache]#

No errors found. Let move on to deploy the roles.

[root@learnitguide apache]# ansible-playbook


/etc/ansible/runsetup.yml
PLAY [node2]
**********************************************************
*****************************************
TASK [Gathering Facts]
**********************************************************
*******************************
ok: [node2]
TASK [apache : Install httpd Package]
**********************************************************
****************
changed: [node2]
TASK [apache : Copy httpd configuration file]
**********************************************************
********
Changed: [node2]
TASK [apache : Copy index.html file]
**********************************************************
*****************
changed: [node2]
TASK [apache : Start and Enable httpd service]
**********************************************************
*******
changed: [node2]
RUNNING HANDLER [apache : restart apache]
**********************************************************
************
changed: [node2]
PLAY RECAP
**********************************************************
*******************************************
node2 : ok=6 changed=5 unreachable=0 failed=0

That's it, We have successfully deployed the Apache webserver using


Ansible Roles to the client node "node2".

Login into the client node "node2" and verify the following things.

[root@node2 ~]# rpm -q httpd


httpd-2.4.6-67.el7.centos.6.x86_64
[root@node2 ~]# systemctl status httpd
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled)
Active: active (running) since Sun 2018-02-04 10:23:44 IST;
1min 58s ago
Docs: man:httpd(8)
man:apachectl(8)

Access the webpage using elinks command or using browser, you will be
able to access it.
[root@node2 ~]# elinks http://node2
This is a homepage created by learnitguide.net for ansible roles.

You might also like