Ansible Basics #4 - Roles

Last Edited: 12/6/2025

This blog post introduces roles and other relevant features in Ansible.

DevOps

In the previous article, we covered grouping and tags to target specific nodes and tasks and several useful modules for managing files, services, and users. As we make use of these features and manage configurations for larger projects with more moving parts, playbooks inevitably become long. Hence, in this article, we will discuss roles and other features that allow us to organize tasks and handle flexible configurations.

Roles

In Ansible, roles can bundle different tasks and other relevant components into separate directories and assign them to different hosts. The following shows how roles can be assigned to hosts in the root main.yaml file.

main.yaml
- host: all
  become: true
  roles:
    - base
 
- host: web_servers
  become: true
  roles:
    - web_servers
 
- host: db_servers
  become: true
  roles:
    - db_servers

The tasks for a role can be organized in the main.yaml file within the <role_name>/tasks subdirectory of the roles directory. For example, we can define tasks for installing Apache and PHP packages for a web_servers role, as shown below.

roles/web_servers/tasks/main.yaml
- name: install apache and php
  package:
      name:
          - "{{ apache_package }}"
          - "{{ php_package }}"
      state: latest
      update_cache: yes

The main.yaml file in the tasks directory is called a taskbook. This is because we only define tasks and do not specify hosts, become, or other fields typically used in a playbook. When executing ansible-playbook main.yaml, the tasks defined in the taskbook for the roles assigned to the hosts are executed as if they were defined in the root playbook.

Host Variables & Handlers & Templates

The above task for the web_server role utilizes templating functionality that can replace host variables. In the previous article, we defined the values of host variables in the inventory file, but we can alternatively define host variables in a <host>.yaml file within the host_vars directory for better organization, as shown below.

253.78.154.178.yaml
apache_package: httpd
php_package: php

We can also use notify instead of register so that any change made in at least one task with notify can properly trigger another task. The task that receives notification from notify is called a handler, and notify uses the handler's name instead of a variable.

roles/web_servers/handlers/main.yaml
- name: restart_apache
  service:
    name: "{{ apache_name }}"
    state: restarted

Handlers can be organized in the main.yaml file within the <role_name>/handlers subdirectory, as shown above. Tasks defined within the same role can trigger a handler using notify: restart_apache. Moreover, we can use templates for host variables in other files as well by employing the template module, as shown below.

roles/base/tasks/main.yaml
- name: generate ssh_config file from template
  tags: ssh
  template:
    src: "{{ ssh_template_file }}"
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: 0644
  notify: restart_ssh

The ssh_template_file is one of the host variables, whose value can be the name of a template file in the roles/base/templates directory (a full path is not required when the template is defined within the role). The ssh_config template can use variables like {{ ssh_users }} and replace them with the values of the corresponding host variables.

boostrap.yaml
host_vars
main.yaml
roles/
├── base/
│   ├── handlers
│   ├── tasks
│   └── templates
...

The above is one potential file structure for managing infrastructure configurations of large projects using Ansible, making use of the features we have discussed. The file structure and features should be chosen based on the project's requirements.

Conclusion

In this article, we discussed roles and other relevant features for organizing various components of Ansible. Ansible files should be managed with Git/GitHub and other DevOps tools like Terraform for proper version control and CI/CD. There are other useful modules and features available, so I highly recommend exploring them.

Resources