UNIT-3 3.2 IWorking With Ansible
UNIT-3 3.2 IWorking With Ansible
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.
vars:
oracle_db_port_value : 1521
tasks:
-name: Install the Oracle DB
yum: <code to install the DB>
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.
[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
• 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>
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.
$ 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.
$ ls
• ansible.cfg hosts roles vivek_orchestrate.retry vivek_orchestrate.yml
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.
PLAY [tomcat-node]
**********************************************************
************
******** *************************************************
\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"
]
}
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"
]
}
"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"
}
• 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.
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.
configure.yml
2. Files
Copy the required files (httpd.conf and index.html) to the files directory.
3. Handlers
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
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.
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
Login into the client node "node2" and verify the following things.
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.