Scripting Playbook in Ansible
(Part-2) Let's deep drive into Playbook and Roles
Table of contents
In a previous blog, we have seen the installation of the Ansible server, its Components, Hosting patterns, Ad-hoc commands, and Modules. There we create two cookbooks with some recipes. With reference to the previous blog https://hashnode.com/post/clh9bb9xc000m09medcxz5ymc
In these blog we are going to discuss about the playbooks, Roles and many more, Let's begin
Playbook
Playbook is written in YAML. It is like a file where you write codes consisting of vars, task, and handlers templates and roles. Each playbook is composed of one or more module in a list, Module is a collection of configuration files.
Playbook is divided into many sections:
Target section: It defines the host against which playbook’s task has to be executed.
Variable section: It defines variables
Task section: It defines list of all modules that we need to run an order.
YAML: (Yet Another Markup Langauge)
For Ansible, nearly every YAML file starts with a list. Each item in the List is a list of key-value pair commonly called a Dictionary.
A Dictionary is represented in a simple Key: Volume form.
All YAML files have to begin “---” and end with “…”,
Indentation is important in playbook.
Prerequisites :
Ansible Master server with Node/Slave ssh Connection
We have describe the above process in previous block, just go through the blog for more clarification.
Create Playbook
Take access of Master server with userlogin
Create one playbook
vi <playBookName.yml>
Edit with YAML scripting
Host, user, connection, etc. are the key and after colon, there is a value for key.
---# target playbook - hosts: <groupName> user: <userName> become: yes connection: ssh gather-facts: yes
To execute the playbook
ansible-playbook <playbookName>
You will get the IP address of the nodes in the output
Creating more such playbook
Installing httpd package
---# target playbook - hosts: <groupName> user: <userName> become: yes connection: yes task: name: install httpd package on linux action: yum name=httpd state= install
Variables:
Ansible uses variables that enable more flexibility in playbook and roles they can be uses to loop through a set of given values, access various information like the hostname of a system and replace strings in templates with specific values. Put the variable section above the tasks so that we define it first and use it later.
Creating Variable playbook
---# Variable playbook
- hosts: <groupName>
user: <userName>
become: yes
connection: yes
vars:
pkgname: httpd
task:
- name: install httpd package on linux
action: yum name="{{lpkgname}}" state= install
Handlers
Handler is same as the task but it will run when called by another task. Handler only runs when task contains a notify directive and also indicates that it changed something.
For Example, To build a home the raw material is necessary, First we have to collect raw material( Install packages) and then start building ( restarting the packages), we have to do these task in ansible using the handlers.
Notify and name of handler must be same
---# My handlers playbook
- hosts: <groupName>
user: <userName>
become: yes
connection: yes
vars:
pkgname: httpd
task:
- name: install httpd package on linux
action: yum name="{{lpkgname}}" state= install
notify: restart HTTPD
handlers:
- name: restart HTTPD
action: service name=httpd state=restarted
Dry Run
To check whether the playbook format is correct or not?
ansible-playbook <playbookName> --check
Loops:
Sometimes you repeat a task multiple time in programming it is called loop. Common ansible loop include changing ownership on server files and/or directories with the file module, creating multiple user with the user
---# target loop playbook
- hosts: <groupName>
user: <userName>
become: yes
connection: yes
vars:
pkgname: httpd
task:
- name: Add the list of user
user: name="{{item}}" state=present
with_items:
-Ram
-Sham
-Sundar
Condition, Vaults, and Role
Condition
when we have different scenarios, then we put condition according to the scenario.
For example, we have different Linux families installed on the node(Ubuntu, Redhat, etc) and we have to install some package on a particular Linux family, in that case the condition statement are used.
When statement: sometimes you want to skip a particular command on a particular node.
Here in the below example are going to install httpd/apache package on both Ubuntu and RedHat machine using the condition statement in a playbook.
---# contional playbook
- hosts: <groupName>
user: <userName>
become: yes
connection: ssh
vars:
pkgname: httpd
task:
- name: install apache on debian
command: apt-get -y install apache2
when: ansible_OS_Family== "Debian"
- name: install apache on Redhat
command: yum -y install httpd
when: ansible_OS_Family== "RedHat"
Vault
Ansible allows keeping sensitive data such as passwords or keys in encrypted files, rather than plain text in your playbooks. we can not open encrypted files through vi command.
For more details regarding vault you can visit https://spacelift.io/blog/ansible-vault
Creating a new encrypted playbook
ansible-vault Create <playbookName.yml>
Will ask to enter assign password
Edit the encrypted playbook
ansible-vault edit <playbookName.yml>
To change the password
ansible-vault rekey <playbookName.yml>
To encrypt an existing playbook
ansible-vault encrypt <playbookName.yml>
To decrypt the encrypted playbook
ansible-vault decrypt <playbookName.yml>
Roles
We can use 2 technologies for reusing a set of task: includes and roles. Roles are good for organizing task and encapsulating data needed to accomplish those tasks. We can organize playbook into a directory structure called Roles. Adding more and more functionality to the playbooks will make it different to maintain in a single file
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,.)
Structure of Role
For example, The Company CEO is running the company of 10 employees, and these 10 employees are working under the two different Managers, one manager is for software solutions and other is for manufacturing solutions. Each manager has a team of 5 employees, employees work according to the manager's instruction and manager is instructed by the CEO of the company
Master.yml file which will work as manager
Roles have one more directory called <webserver> that will work as a supervisor which will be the actually Role name
The <webserver> directory contains number of directories, that will work as the employee and these each directory contains the main.yml file
A Playbook section are constructed seperatly in respective directories (<task> <handlers>etc) they also contain main.yml file which has yaml scripting for roles, These directories are store in particular directory inside the Roles directory. Master.yml file contains the target information and Roles specification, Whenever we called the Master.yml file according to roles we will get results.
Defining Roles in Playbook
Create the parent directory in playbook
mkdir –p playbook/roles/<webserver>/<tasks>
Go inside playbook directory
cd playbook
Create main.yml file in <tasks> directory and edit main.yml file with yaml scripting
touch /roles/webserver/tasks/main.yml
Editing of main.yml file,
vi roles/webserver/tasks/main.yml
- name: install apache on RedHat
yum: pkg=httpd state=latest
Create the master.yml file and edit it,
touch /master.yml
Editing the file,
vi master.yml
---# Master playbook for Webserver - hosts: <groupName> user: <userName> become: yes connection: ssh roles: - webserver
--- # Master playbook for Webserver
- hosts: <GroupName>
user: ansible
become: yes
connection: ssh
roles: - webserver
Execute the playbook
ansible-playbook master.yml
In these way, we can create multiple directories in Role and assign them in the master file so that we can execute the role on the node machine.
Here we conclude Ansible topic,
Stay tuned!!
For any query, you can contact to Atharva Deshpande