Part 4: Creating Ansible Roles
Why stop at playbooks, when you can bundle them?
- Sebastiaan
- 4 min read
Why Roles over Playbooks?
Single playbooks are great for tasks but when a project starts getting complexer, it way more managable in a role then a single playbook. Ansible role is a predefined set of playbooks that is build for a specific purpose. All the necessary configurations can be set and build into the role.
Creating the role
We create the role in the folder we’ve been using in the previous parts /Users/sebas/Desktop/ansible.
With following command we can create a pre-setup role through ansible.
ansible-galaxy init /Users/sebas/Desktop/ansible/<name role>
Role layout
This is the layout of the pre-setup role we’ve created through the previous command.
machine_info # Name of the role (created through the init command)
├── README.md # Default setup for a readme of the role
├── defaults # Standard config place, which can be used in tasks
│ └── main.yml
├── files # Place here all necessary files needed for your role
├── handlers # Default place for adding task handlers
│ └── main.yml
├── meta # Informational place when you list your role to the internet
│ └── main.yml
├── tasks # Tasks folder where playbooks go
│ ├── 00_gather_facts.yml
│ ├── 01_hostname.yml
│ ├── 02_ram.yml
│ └── main.yml
├── templates # A place for all templated files which can be used in tasks often defined in jinja templates.
├── tests # Created for testing your role
│ ├── inventory
│ └── test.yml
└── vars # The is the folder for role specific variables.
└── main.yml
Tasks files
Each of these tasks files is a separate playbook but together they create a role which can configure or build a service.
We use a special var called ansible_facts, this is information from ansible.builtin.setup.
In the next part (5) we will go further into detail about vars and secrets.
To show the output of the special var we use the ansible.builtin.debug module.
00_gather_facts.yml
In this playbook we gather all the information that ansible can learn. This is can be the gather_facts = true toggle in a single playbook.
---
- name: Gather facts
ansible.builtin.setup:
gather_subset:
- 'all'
01_hostname.yml
In this playbook we want to know what distribution the machine is running and which version.
---
- name: Get distribution
ansible.builtin.debug:
var: ansible_facts.distribution
- name: Get distribution_version
ansible.builtin.debug:
var: ansible_facts.distribution_version
- name: Get hostname
ansible.builtin.debug:
var: ansible_facts.nodename
02_ram.yml
We also want to know how much RAM we have and how much is used.
---
- name: Get free ram
ansible.builtin.debug:
var: ansible_facts.memfree_mb
- name: Get total ram
ansible.builtin.debug:
var: ansible_facts.memtotal_mb
main.yml
This is the file where every separate playbook comes together to bind the role together.
---
- name: Get facts
ansible.builtin.include_tasks: 00_gather_facts.yml
- name: Get hostname
ansible.builtin.include_tasks: 01_hostname.yml
- name: Get ram
ansible.builtin.include_tasks: 02_ram.yml
Creating the playbook which runs the role
touch /Users/sebas/Desktop/ansible/role_book.yml
Lets copy the following configurion into the role_book.yml file.
Ansible uses the roles part in the configuration to know that it is a role which needs to be run.
Because this role is in the same directory as the role_book playbook is doesn’t matter.
When you place your role somewhere else you need to add a path like role: <path>/role_name
---
- name: playbook
hosts: localhost
roles:
- role: machine_info
We use the same command to run a playbook, but now inside the playbook there is a role defined. The working of the command is the same, Ansible knows when it needs to search for the main.yml file in the role when the roles tag is used.
ansible-playbook role_book.yml
Output
sebas@eyeofmordor ansible % ansible-playbook role_book.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
PLAY [playbook] ****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [machine_info : Get facts] ************************************************
included: /Users/sebas/Desktop/ansible/machine_info/tasks/00_gather_facts.yml for localhost
TASK [machine_info : Gather facts] *********************************************
ok: [localhost]
TASK [machine_info : Get hostname] *********************************************
included: /Users/sebas/Desktop/ansible/machine_info/tasks/01_hostname.yml for localhost
TASK [machine_info : Get distribution] *****************************************
ok: [localhost] => {
"ansible_facts.distribution": "MacOSX"
}
TASK [machine_info : Get distribution_version] *********************************
ok: [localhost] => {
"ansible_facts.distribution_version": "15.2"
}
TASK [machine_info : Get hostname] *********************************************
ok: [localhost] => {
"ansible_facts.nodename": "eyeofmordor"
}
TASK [machine_info : Get ram] **************************************************
included: /Users/sebas/Desktop/ansible/machine_info/tasks/02_ram.yml for localhost
TASK [machine_info : Get free ram] *********************************************
ok: [localhost] => {
"ansible_facts.memfree_mb": "6562"
}
TASK [machine_info : Get total ram] *********************************************
ok: [localhost] => {
"ansible_facts.memtotal_mb": "8192"
}
PLAY RECAP *********************************************************************
localhost : ok=10 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
How to use variables
Variables are a great way of setting informations which can be reused on different places within our playbook or role. This url does a deepdive in variables https://spacelift.io/blog/ansible-variables and does a great way of explaining how to use it.
Conclusion
When you when want to keep all the necessary files together for projects or configurations. Roles is a great solution for this, there is always a playbook needed to call on the role itself.
Stay tuned for the Part 5: Secrets!
- Tags:
- Ansible