Saturday, April 26, 2025

An Ansible Journey 13: Roles

Roles provide the user will separating out different blocks of code for ease of reading. In this context can be thought of as the role that the target server plays in the environment. They allow you to move code into other files, keeping the playbook cleaner. Fortunately, using roles doesn't restrict you from categorizing work; you can still have, for example, a role called web_servers and still differentiate between say, a web server that is public-facing and a web server for internal use (which may have relaxed security requirements).

In one of the earlier videos, Jay split up his playbook into two two: the bootstrap.yml file and the site.yml. Roles takes this a step further.

Creating roles is very straight-forward, requiring only two general modifications to a playbook with all tasks in one file: directory structure changes and moving code blocks to a new file or files.

Directory Changes

Roles imposes a standard for using roles in your filesystem. In general, no directory is required unless there are files in that directory. Here is an example:

opt/
    ansible/
        inventory/
        playbooks/
            site.yml
            roles/
                base/
                files_servers/
                    tasks/
                        main.yml
                web_servers/
                    files/
                        landing_page.yml
                    tasks/
                        main.yml

Under playbooks we create a directory called roles. That contains a directory for each server role we are defining. The base role is one that would likely apply to all servers, containing such items as the implementation of organizational security policies, support team configurations, etc. Within each role, we have at a minimum, a tasks directory. We can optionally add additional directories, like files, if there are files that we will be transferring to our target servers. Finally, within each tasks directory, we have a file called main.yml. The directory corresponding to a role is required, as is the tasks directory, and the main.yml file.

Code Changes

In the previous model, we created roles by using the [role-name] construct in our playbook:

playbook.yml file
    [base]
        (plays intended for all hosts)
    [web_servers]
        (plays intended for all web servers)
    [db_servers]
        (plays intended for all database servers)
    [file_servers]
    ...

The playbook.yml file will have all plays removed, with each set of plays being defined in its respective main.yml file underneath tasks:

playbook.yml file:

- hosts: all
  become: true
  pre_tasks:
    (any plays that will be run on any server, with each run.*)

- hosts: all
  become: true
  roles:
    - <rolename>
...

main.yml file

- name: Install Nginx Web Service
  tags: nginx,ubuntu,web
  apt:
    name:
      - nginx-core
      - nginx-doc
    state: latest
  when: ansible_distribution == "Ubuntu"

- name: Enable HTTPS in Nginx - Rocky
  tags: nginx,rocky,web
  lineinfile:
    path: "/etc/nginx/nginx.conf"
    line: "        listen       *:443 ssl;"
    insertafter: 'listen       80'
    firstmatch: true
    backup: true
  when: ansible_distribution == "Rocky"
  register: nginx_conf
... 

The playbook.yml file retains each section it did before, but we replace the plays with:

  roles:
    - <rolename>

Then, we take the plays that were in the playbook.yml file and place them into the main.yml file. We'll retain the tags so we can continue to narrow the scope of each run during testing, quick patch activity, etc. One thing to note that is not clear in the example is that whereas the plays are indented two spaces in the playbook.yml file, they start on the left (column 1). This is due to the YAML requirement that all code begin on the left. Note that the first line of our playbook.yml file (---) is not required in the main.yml files.

The main.yml file (and any other collection of plays) in the tasks directory are referred to as "taskbooks."

 

<PREV - CONTENTS - NEXT>

No comments:

Post a Comment