Code redundancy is improved when using Ansible to administer the same service across various environments or products. It becomes more challenging to handle everything within a single Ansible playbook file as functionality becomes more complicated. Coding amongst teams becomes challenging. To address these issues, Ansible Roles are used.
In this Answer, we will provide a clear understanding of Ansible roles and go through a practical example of using them. The prerequisites for this Answer are as follows:
A Linux OS or Virtual Machine (preferably Ubuntu OS)
Ansible installed on it
Roles are a way to organize and package Ansible tasks, variables, templates, and other configuration files in a reusable and modular manner. Roles provide a structured way to manage configurations and deployments across multiple hosts, making it easier to manage complex infrastructure and automate repetitive tasks.
Configuration management
Application deployment
Infrastructure provisioning
Security hardening
Custom automation tasks
Continous Integration and Continous Deployment (CI/CD)
YAML files with a preset directory structure are used to establish roles. Directories such as defaults
, vars
, tasks
, files
, templates
, meta
, and handlers
can be found in a role directory hierarchy. An appropriate main.yml file with the necessary content must be present in each directory.
Let’s simply go over the directories mentioned above:
defaults
: This defines the role’s preset variables. Default variables have the lowest priority, making them simple to change.
vars
: It includes the role’s variables. Variables in the vars directory are given precedence over those in the defaults directory.
tasks
: These consist of the primary set of actions that the role must take.
files
: It has files that we wish to copy to the remote host. The path to the resources kept in this directory does not need to be defined.
templates
: This includes a file template that allows changes from the role. For building templates, we employ the Jinja2 templating language.
meta
: They include additional role information, including author, support platforms, and dependencies.
handlers
: They include controllers connected to services that can be called by “inform” directives.
To set up the nginx server using Ansible roles, we must define the roles in the playbook.yml
file, which acts as the role’s caller. Additionally, we will examine the folder hierarchy of our playbook to ensure the proper organization of files and directories. This approach will help us apply all the knowledge we have gained while setting up the nginx server.
nginx/defaults/main.yml
file---nginx_gzip_comp_level: 6nginx_gzip_buffers: "16 8k"nginx_gzip_types:- "text/plain"- "text/css"- "application/json"- "application/javascript"- "text/xml"- "application/xml"- "application/xml+rss"- "text/javascript"
When no other value or variable is supplied for the role, the default variables defined in the code above are used.
nginx/handlers/main.yml
file---- name: restart nginxsystemd:name: nginxstate: restarted
When the playbook runs, handlers will alert us when nginx has been restarted.
nginx/tasks/main.yml
file---- name: install nginxapt:name: nginxstate: latestbecome: truenotify: restart nginx- name: copy nginx configuration filetemplate:src: templates/nginx.conf.j2dest: /etc/nginx/nginx.confbecome: true
The tasks file sets up nginx and configures the server by the configuration template specifications.
nginx/templates/nginx.conf.j2
fileuser {{ nginx_user }};worker_processes {{ nginx_worker_processes }};pid /run/nginx.pid;events {worker_connections {{ nginx_worker_connections }};}http {sendfile on;tcp_nopush on;tcp_nodelay on;keepalive_timeout {{ nginx_keepalive_timeout }};types_hash_max_size 2048;include /etc/nginx/mime.types;default_type application/octet-stream;# Logging Settingsaccess_log {{ nginx_access_log }};error_log {{ nginx_error_log }};# Gzip Settingsgzip on;gzip_disable "msie6";gzip_vary on;gzip_proxied any;gzip_comp_level 6;gzip_buffers 16 8k;gzip_http_version 1.1;gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;# Default Server Blockserver {listen {{ nginx_server_listen }} default_server;listen [::]:80 default_server;root {{ nginx_root }};{{ nginx_index }};server_name {{ nginx_server_name }};location / {try_files $uri $uri/ =404;}}}
The Jinja2 templating language creates templates for the nginx configuration file, providing more abstraction and making updates simple.
nginx/vars/main.yml
file---nginx_user: www-datanginx_worker_processes: autonginx_worker_connections: 768nginx_keepalive_timeout: 65nginx_gzip: truenginx_access_log: /var/log/nginx/access.lognginx_error_log: /var/log/nginx/error.lognginx_server_listen: 80nginx_server_name: _nginx_root: /var/www/htmlnginx_index: "index index.html index.htm index.nginx-debian.html"
The variables utilized throughout the role are stored in the vars/main.yml file. It aids in maintaining the role structure well-packaged and ordered.
playbook.yml
file- name: Install Nginxhosts: localhostconnection: localbecome: trueroles:- nginx
This is the primary file of the ansible-playbook and is the caller of the nginx role. For this practical example, the host is our local machine.
If we properly followed the hands-on example, this command, ansible-playbook playbook.yml
, will be used to execute the playbook.
The output of the command above may be similar to the picture below:
To check if nginx has been installed and is working properly, we go to our browser and type localhost:80
or in our terminal curl localhost:80
.
Ansible roles are good to use when a playbook starts becoming complex and during a collaboration project, and keep the structure of the playbook organized.
Free Resources