IT 3110: System Automation

Ansible roles


Roles

Roles are ways of automatically loading certain vars_files, tasks, and handlers based on a known file structure. Grouping content by roles also allows easy sharing of roles with other users.

Essentially, this could be used to split a monolithic playbook into more manageable pieces.


Role Directories

My directory structure looks something like this:

    nfs
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── README.md
    ├── tasks
    │   └── main.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml

Role Directories


Role Tasks

You can add other YAML files in some directories. For example, you can place platform-specific tasks in separate files and refer to them in the tasks/main.yml file:

    # roles/example/tasks/main.yml
    - name: Install the correct web server for RHEL
      import_tasks: redhat.yml
      when: ansible_facts['os_family']|lower == 'redhat'

    - name: Install the correct web server for Debian
      import_tasks: debian.yml
      when: ansible_facts['os_family']|lower == 'debian'

    # roles/example/tasks/redhat.yml
    - name: Install web server
      ansible.builtin.yum:
        name: "httpd"
        state: present

    # roles/example/tasks/debian.yml
    - name: Install web server
      ansible.builtin.apt:
        name: "apache2"
        state: present

Role

By default, ansible looks for roles in 2 locations:

Could also call with a fully-qualified path. (i.e. /opt/ansible/roles/common )


Role Execution

There are two ways to invoke roles. Classic way:

    ---
    - hosts: webservers
      roles:
         - common
         - webservers

Role Execution

Another way to invoke a role:

    ---

    - hosts: webservers
      tasks:
      - ansible.builtin.debug:
          msg: "before we run our role"
      - include_role: #or import_role
          name: example

Role Execution

Ansible only executes each role once, even if you define it multiple times, unless the parameters defined on the role are different for each definition. For example, Ansible only runs the role foo once in a play like this:

    ---
    - hosts: webservers
      roles:
        - foo
        - bar
        - foo

Role Execution

If you want the role to run more than once:


Role Execution

Another way to have the same role run twice.

    # playbook.yml
    ---
    - hosts: webservers
      roles:
        - foo
        - foo

    # roles/foo/meta/main.yml
    ---
    allow_duplicates: true

Role Creation

An easy way to create the directory structure is