Skip to content

Latest commit

 

History

History
120 lines (88 loc) · 6.13 KB

31-handelers-roles.md

File metadata and controls

120 lines (88 loc) · 6.13 KB

Handlers and Roles in Ansible

In the last session we configured our servers by installing httpd package. As time goes on and projects grow, additional playbooks and variable files are added, and task files may be split. To follow the best practice by way of organizing all the tasks in a more efficient way so we can make playbooks more maintainable, reusable, and powerful. Ansible provides flexible features by providing us the tools necessary to split up tasks more efficiently using Includes and Roles. In this session, we will build upon the earlier example and use Ansible Galaxy command to make use of roles and includes.

All the manifest files for this demo can be found here

Before jumping on to Roles, let's check out Handlers in Ansible. Sometimes you want a task to run only when a change is made on a machine. For example, you may want to restart a service if a task updates the configuration of that service, but not if the configuration is unchanged. Ansible uses handlers to address this use case. Handlers are tasks that only run when notified.

In the Playbook, I've added another play and some variables and added a template file to our server at /var/www/html to display a custom page. I've also added a notify property to that task. Here the notify keyword instructs the Add Apache index.html file task to run the Handlers - restart httpd in our case.

Playbook-Handlers

Then from line 22 onwards, we define our handler. Which is a task in itself, which will run every time we make a modification in the Add Apache index.html file task and will restart the Apache service. As we have modified Apache's default welcome page.

Variables

As you might notice, I have provided some variables in the Playbook. Alternatively, One of the ways we can use variables is by creating a separate variables.yaml file in the same directory and declaring all the required variables in that file, and reference that file in our playbook using the vars_files keyword:

---
- hosts: all
become: yes
vars_files:
- variables.yaml

After running this playbook using either of the methods, we get the same result. We should see our custom welcome message as we navigate to one of our servers.

Server-Output

Roles

Currently, we have two tasks and a Handler in our playbook, This can grow exponentially as we work on our projects, where we will have to add more configurations to our servers. We might end up with something resembling Russian nesting dolls. That is where Ansible Roles comes to the rescue. Ansible Roles allows us to include Playbooks inside other Playbooks. Roles bring together these different facets of Ansible code creation to provide a fully independent collection of variables, tasks, files, templates, and modules that can be reused again in different playbooks. Roles have a structured layout on the filesystem. We can use the ansible-galaxy role init command, which will help us build skeleton directory structures for new roles. Roles-tree We can see that the above command has scaffolded the directory structure for the httpd Role. When creating a role, not every directory or file is required. Only files that exist will be processed. We shall move our current project with the newly created role/httpd. Once, we have the skeleton ready for our httpd role, we shall start to configure our role. First, we will move our current tasks in the Playbook to the tasks directory in the roles folder. Accordingly, we will move the templates, handlers, variables, and any other content to relevant folders. Now, the contents of various folders in the roles will include as fllowing:

tasks folder would include a install_httpd.yaml file:

- name: Install Apache package
yum:
name:
- httpd
- name: Add Apache index.html file
template:
src: templates/index.html.j2
dest: /var/www/html/index.html
notify:
- restart httpd

and the main.yaml would be used to import that task within our playbook:

 - -
# tasks file for role/httpd
- include_tasks: install_httpd.yaml

The var folder will include the declared variables in the main.yaml file:

 - -
# vars file for role/httpd
welcome_msg: "Welcome to #90DaysOFDevOps"
day: 32

The templates folder will include our index.html.j2 jinja template file:

<html>
<h1>{{ welcome_msg }}</h1>
<h2> This is Day {{ day }} of the project </h2>
<h2>and we are learning to work with Roles in Ansible</h2>
<a href="https://github.com/Santosh1176/90DaysOfDevOps" alt=githublink>Check out the Github Link</a>
</html>

And finally, the handlers folder will include a main.yaml which would be triggered from our playbook.

 - -
# handlers file for role/httpd
- name: restart httpd
service:
name: httpd
state: started
enabled: yes

Calling Roles from the Playbook

Once we've configured all the roles in relevant directories. we are ready to use that role in our playbook1.yaml file:

 - -
- hosts: all
become: yes
roles:
- httpd

We just call the role httpd and that's it. Ansible will take of importing all the relevant configuration details from the roles directory and configure our servers.

AS we apply our playbook with the same ansible-playbook playbook1.yaml - limit app command, we can see the servers being configured.

Apply Playbook

You can see in the TASK header that the tasks were imported from roles we had defined:

TASK [httpd : include_tasks] *****************************************************************************************************************
included: /home/santosh/ansible-demo/roles/httpd/tasks/install_httpd.yaml for 192.168.60.4, 192.168.60.5

After applying the playbook with roles configured, we get the same configuration on our server. The main difference is that all the peices of configuration are segregated according to their responsibility and our project is more structured.

Roles Result