Scripting Playbook in Ansible

(Part-2) Let's deep drive into Playbook and Roles

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

  1. Create one playbook

    vi <playBookName.yml>

  2. 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
      
  3. To execute the playbook

    ansible-playbook <playbookName>

You will get the IP address of the nodes in the output

  1. 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

  1. Create the parent directory in playbook

    mkdir –p playbook/roles/<webserver>/<tasks>

  2. Go inside playbook directory

    cd playbook

  3. 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

  4. 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

  5. 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