Reusable playbooks, Ansible roles

So, in this blog I have told you about “what is Ansible, playbooks, hosts?” now it is the time to go further with roles. In the world of programming we have a principle called DRY which is “Don’t repeat yourself” means don’t do any work again and again. For that we try to make a process that we have to write the code one time and we can use it again and again without rewriting the whole code again and again.

In the era of automation Ansible also gives us a certain technique that if we need a part of playbook multiple files then we can write it inside a role and use it again and again. It also helps us to reduce the complexity of the code like it is always better to break down a big playbook in a small parts and use it.

Basically for the role we define it inside a roles directory. inside this directory we define or every role and inside the role their will be multiple directories below you can see it –

$ tree .
.
├── roles
│   └── webservers
│       ├── defaults
│       ├── files
│       ├── handlers
│       ├── meta
│       ├── tasks
│       ├── templates
│       └── vars
└── web.yml

Roles expect files to be in certain directory names. Roles must include at least one of these directories, however it is perfectly ok to exclude any which are not being used. When in use, each directory must contain a main.yml file, which contains the relevant content:

  • tasks – contains the main list of tasks to be executed by the role.
  • handlers contains handlers which may be used by the roles or elsewhere in the code.
  • defaults contains variables for the roles.
  • vars contains other variables for the roles.
  • files contains files which will deploy by the roles.
  • templates contains templates which can be deployed via roles.
  • meta contains meta data.

So, now see by example how roles helps us in the various aspects of automation. Below the code is without roles –


---
- hosts: webservers
  gather_facts: yes
  remote_user: root
  become: true
  tasks:
    - name: Ensure group {{ item }} exist
    group:
      name: "{{ item }}"
      state: present
    loop:
      - mozilla
      - dgplug
  - name: add several users to several group
    user:
      name: "{{ item.name }}"
      state: present
      groups: "{{ item.groups }}"
    loop:
      - { name: 'testuser1', groups: 'mozilla' }
      - { name: 'testuser2', groups: 'dgplug' }
  - name: remove several users to several group
    user:
      name: "{{ item.name }}"
      state: absent
      groups: "{{ item.groups }}"
    loop:
      - { name: 'testuser1', groups: 'mozilla' }
      - { name: 'testuser2', groups: 'dgplug' }

Now see how we can implement this via roles –

# web.yml
---
- hosts: webservers
  become: true
  roles:
    - role: '/home/aniruddha/Desktop/ansible-playbook/roles/webservers'

# roles/webservers/tasks/add_group/main.yml
---
tasks:
  - name: Ensure group {{ item }} exist
  group:
    name: "{{ item }}"
    state: present
  loop:
    - mozilla
    - dgplug

# roles/webservers/tasks/add_user_to_group/main.yml
---
tasks:
  - name: add several users to several group
  user:
    name: "{{ item.name }}"
    state: present
    groups: "{{ item.groups }}"
  loop:
    - { name: 'testuser1', groups: 'mozilla' }
    - { name: 'testuser2', groups: 'dgplug' }

# roles/webservers/tasks/remove_user_from_group/main.yml
---
tasks:
  - name: Remove several users from different group
  user:
    name: "{{ item.name }}"
    state: absent
    group: "{{ item.groups }}"
  loop:
    - { name: 'testuser1', groups: 'mozilla' }
    - { name: 'testuser2', groups: 'dgplug' }

Thank you 🙂