Packaging and Ansible Roles
From bib. source
Wouldn’t it be nice if there were a way to take bits of related configuration, and package them together nicely? […], what if we could take these packages […] and make them flexible so that we can use the same package throughout our infrastructure, with slightly different settings on individual servers or groups of servers?
A package in Ansible is a particular organization or structure of the Ansible code or configuration management that can be installed, often allowing for slightly different settings. Such a package is possible to make through the use of Ansible roles (Geerling 2023, 131). There is no need to explicitly include files or playbooks for a role, but rather “Ansible automatically includes any main.yml files inside specific directories that make up the role¨ (Geerling 2023, 132).
Role root directory
A role, then, is a directory structure, with the root directory path having the name of the role, and a set of sub-directories, as follows (Ibid):
role_name/
meta/
tasks/The meta and tasks child directories
The directories that make up any role include meta and tasks, each of which can therefore have under them a main.yaml file (Ibid). Ansible will not only automatically include such main.yaml files in these directories, but will execute or run whatever is specified in them when the name of the role is called (i.e., when the parent directory name is mentioned or referenced) (Ibid). E.g., “if you call the role from your playbook […]¨ using the roles field (which takes a list of role names as a value) then “Ansible will run all the tasks defined in tasks/main.yml¨ (Ibid):
---
- hosts: all
roles:
- role_nameMeanwhile, use of a main.yaml file inside of the meta sub-directory of any given role allows for defining meta information about the role/package (Geerling 2023, 133). Most importantly, a dependencies field can be defined inside of main.yaml that lists other roles that need to be run prior to the given role (Ibid).
If the playbook needs to run some tasks before a role is executed, one should use a pre_tasks field at the equivalent level in the YAML hierarchy as roles (Geerling 2023, 134). Any tasks after execution of roles is just like any regular task specification in a playbook, i.e. using the tasks field at the same level of the hierarchy (Ibid). Here is an example (Ibid):
pre_tasks:
# EPEL/GPG setup, firewall configuration
roles:
- nodejs
tasks:
# Node.js app deployment tasks...The handlers child directory
From bib. source
You can store handlers directly inside a
main.ymlfile inside a role’shandlersdirectory.
Because Ansible handlers have the same syntax as tasks, not much needs to be said about what that main.yml file in the role’s handlers directory would look like. The handlers enlisted in that file can consequently be called “just like those included directly in your playbooks¨ (Geerling 2023, 138).
The vars and defaults child directories
From bib. source
When running a role’s tasks, Ansible picks up variables defined in a role’s
vars/main.ymlfile anddefaults/main.yml[…], but will allow your playbooks to override the defaults or other role-provided variables if you want.
That is, a role also can have a corresponding sub-directory vars or defaults, either of which allow specification of variables for that Ansible role (Geerling 2023, 135). For example, the variable node_npm_modules can be specified in defaults/main.yml (Ibid):
---
node_npm_modules:
- foreverThese role variables can then be used in the role’s master task file or playbook (Ibid). This variable can also be overridden in the playbook which references this role (Geerling 2023, 136):
node_npm_modules:
- forever
- async
- requestEither way, the given playbook must have been modified to mention the role’s variable–in this case, node_npm_modules (Geerling 2023, 135):
---
- name: Install Node.js (npm plus all its dependencies).
dnf: name=npm state=present enable=epel
- name: Install npm modules required by our app.
npm: name={{ item }} global=yes state=present
with_items: "{{ node_npm_modules }}"If this role with its custom variable is executed via a playbook, “all three of the […] npm modules will be installed,¨ i.e. the forever, async, and request npm modules aforementioned (Geerling 2023, 136).
The files and templates child directories
From bib. source
[…], let’s assume our role is structured with files and templates inside
filesandtemplatesdirectories, respectively: […]
That is to say, roles can also contain a files and templates sub-directory. The former in particular is a convenient root directory or root folder for file storage. Namely, one can place files there that are to be copied or transferred via Ansible and its modules, or even used in other ways by Ansible (Geerling 2023, 138). The way to make use of a file within the files directory is to (Ibid):
From bib. source
[…], add the filename or the full path from within a role’s
filesdirectory, […]
For example, in src for Ansible’s copy module you can reference the filename of a file inside the given role’s files (Ibid):
- name: Copy configuration file to server directly.
copy:
src: example.conf
dest: /etc/myapp/example.conf
mode: 0644The same steps apply for usage of the files in the role’s templates directory, except that such a file is likely to have a different purpose than a file under the role’s files directory.
Path of Ansible Roles
These roles are stored in “a roles folder in the same directory as your main playbook file¨ if not “the default global Ansible role path¨ found/configured “in /etc/ansible/ansible.cfg¨ (Geerling 2023, 132).
directory_path root_directory file_path filepath reference mention parent_directory child_directory folder parent_folder child_folder root_folder configuration_management packages server configuration_file playbooks task module
bibliography
- “Playbook Organization - Roles, Includes, and Imports.” In Ansible for DevOps: Server and Configuration Management for Humans, 2nd ed., 123–147. Leanpub, 2023.