Day 3- Ansible Roles: From Chaos To Order
Introduction
An Ansible Role is an important feature of the Ansible tool that provides a structured way to organize plays, files, templates, variables, handlers, etc. This helps us to simplify complex Configuration Management and Automation as the tasks are attributed to a specific role. Unlike usual Ansible playbooks where all the tasks are written in a single file which makes it look complex, Ansible roles come into the picture by bifurcating the Playbook into different specified YAML files under various sections such as files, vars, tasks, and handlers.
Importance of roles in managing playbooks
Better organization and scalability.
Ansible Roles improve playbook readability and collaboration.
Ansible Roles allow us to reuse common configuration steps between different types of servers
Understanding Ansible Roles
Structure of an Ansible Role
Ansible Role has the following important components
Tasks
Contains the main list of tasks to be executed by the role
Default File:
main.yml
Handlers
Handlers are the special tasks that are triggered by the actions of the other tasks.
Usually used to restart or reload the services when a task changes the state of the system
Default File:
main.yml
Files
Contains the static files to be transferred to target nodes/hosts.
The files can be referenced using the
copy
andtemplate
module in thetasks
Templates
Contains Jinja2 templates, which can include variables that are dynamically replaced when the role is executed.
Templates are used for configuration files where values are substituted dynamically from variables.
Vars
Stores variables with a higher priority than the Default Variables. Difficult to override.
Defaults
Stores the default variables for the role
Default File:
main.yml
Meta
Contains metadata about the role, including dependencies on other roles.
Default File:
main.yml
Tests
Contains test files for verifying that the role works as expected.
inventory
is the test inventory file.test.yml
is a playbook to test the role.
README.md
Provides an overview of what the role does, how to use it, and any specific requirements or configurations needed.
Creating Ansible Roles
Let us understand the Ansible Roles by practically working on a problem statement.
Problem statement:
An ansible cluster having a test node and a prod node with a control/master node is set up. On test, Nginx and on prod Apache webserver needs to be installed using Ansible roles nginx and apache respectively. The default webpage hosted on the server should be updated with a custom webpage
Setting up the ansible environment
We already have the environment set up with a master Ansible server and cluster of test and prod servers.
The ansible installation steps can be accessed here.
The host inventory has the following hosts mentioned
Setting up a role directory
Creating two roles ‘nginx’ and ‘apache’ using the below galaxy command
cd /etc/ansible/roles
sudo ansible-galaxy init <rolename>
To visualize the role directory structure, we need to install the tree
package
sudo apt install tree
tree <rolename>
More about Ansible Galaxy for role structure
Ansible Galaxy is a community-driven hub where we can find, share, and download Ansible roles and collections. It simplifies role management by providing a central platform to access reusable content, so we don’t have to start from scratch. Whether we need to set up a web server, manage databases, or automate other tasks, Galaxy offers ready-made roles to speed up our workflow. Plus, we can share our roles with others, contributing to the community and benefiting from the work of others.
https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html
Nginx Role Configurations
Navigate to
tasks
dir and edit main.yml file to include the below yaml filesinstall.yml, configure.yml, service.yml
sudo touch install.yml configure.yml service.yml
sudo vi main.yml
The
install.yml
will have steps to install nginxThe
configure.yml
will contain yaml command to copy a custom webpage code to be configured on a remote host. We will keep it blank for now.The
service.yml
will have the steps to start the services.-
Apache Role Configuration
Similar to the Nginx role, we will configure the details for Apache2 as well.
service.yml
install.yml
service.yml
Creating the main playbook:
roles.yml
Navigate to playbooks dir inside /etc/ansible/playbooks
and create a roles.yml
file as follows
Let’s check the syntax before running the playbook
ansible-playbook —syntax-check roles.yml
Encountered an error stating role is not a valid attribute for play.
Rectifying the error by updating role
to roles
The roles.yml file’s syntax is ok with a warning that the configure.yml file is empty which is ok.
Running the playbook
The playbook has failed at task of service restart for nginx.
TASK [nginx : nginx service start and enbale] ******************************************************************************************************************** fatal: [test1]: FAILED! => {"changed": false, "msg": "Unable to start service nginx: Job for nginx.service failed because the control process exited with error code.\nSee "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details.\n"}
Troubleshooting the issue:
This error has occurred because the port 80
to which nginx listens is already in use
Another website is already hosted on the port 80 :
The webpage was hosted on apache as a part of earlier project
I have purged the apache on test server
sudo apt purge apache2
Rerunning the Playbook
Playbook ran successfully!
The test and prod have successfully hosted the nginx and Apache websites
nginx on test
apache on prod
Now, let us update the webpage by updating configure.yml
We will update the Nginx webpage with a static webpage placed inside the Files
folder.
Updating the configure.yml file
Here, we have used notify
that triggers the handler’s task to restart Nginx
Now, let us update the configure.yml and other dependencies for the Prod server update
We will define a variable, which will be used in the custom template of the webpage
cd /etc/ansible/roles/apache/vars
vi main.yml
We will create a template named index.html.j2 - a Jinja2 file that will get updated on the remote Prod server.
Here, the variable defined inside the vars folder is used in the file. Jinja2 replaces
{{ custom_hostname }}
with the actual hostname at the time of playbook execution.
Creating a configure.yml
file
/etc/ansible/roles/apache/tasks
Updating the Handlers
/etc/ansible/roles/apache/handlers/main.yml
Running the roles.yml
playbook
cd /etc/ansible/playbooks
ansible-playbook --check roles.yml
It failed due to incorrect indentation in handlers of nginx role
Rerunning the playbook
ansible-playbook roles.yml
Webpage updated as well
Nginx:
Apache2:
Conclusion
Ansible roles enforce the structure and reusability of all our automation tasks so that we can work comfortably with configurations across different environments. With its power, complex processes become more scalable and reduce redundancy in the playbooks. From deploying web servers to managing the infrastructures, Ansible roles represent clean and efficient ways to deliver precision towards our automation goals. As we continue on to hone our automation abilities, mastering roles will become one of the bedrocks in our arsenal of DevOps, smoothing the deployment process and making for more robust systems!!
Subscribe to my newsletter
Read articles from Akash Sutar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by