This post covers the use of host variables and handlers. these offer a way to reduce the lines of code used to specify an infrastructure, and to extend the functionality of a play or task.
Host Variables
Host variables are defined in a host_vars directory that resides in your playbooks directory. Each file must be named exactly as the hostname (or IP address/FQDN) in your inventory file. In my host_vars directory, I have three files:
[ansadm@rocky-1 ansible]$ ll playbooks/host_vars/
total 12
-rw-rw-r--. 1 ansadm ansadm 91 Apr 26 15:18 192.168.5.250.yml
-rw-rw-r--. 1 ansadm ansadm 87 Apr 26 12:48 192.168.5.251.yml
-rw-rw-r--. 1 ansadm ansadm 88 Apr 26 12:51 192.168.6.30.yml
[ansadm@rocky-1 ansible]$
Although these files all have a .yml extension, the use of "---" on the first line is optional. Within that file, we specify each variable using a key/value pair syntax:
[ansadm@rocky-1 ansible]$ cat playbooks/host_vars/192.168.5.250.yml
---
nginx_package_name: nginx
nginx_service_name: nginx
extra_package_name: pcp-pmda-nginx
Once your variables file is created, you can reference the individual variables using Ansible's variable syntax:
"{{ variable-name }}"
In our web_servers role, our first task instructs the dnf module to install two packages, nginx and pcp-pmda-nginx:
- name: Install Nginx Web Service
tags: nginx,web
dnf:
name:
- nginx
- pcp-pmda-nginx
state: latest
with the host variables file shown above, we can obtain the same result referencing the variable names:
- name: Install Nginx Web Service
tags: nginx,web
dnf:
name:
- "{{ nginx_package_name }}"
- "{{ extra_package_name }}"
state: latest
Upon execution, Ansible will replace "{{ nginx_service_name }}" with "nginx."
In a case where the same variable may have a different value across different operating systems, we could specify the same variable name with different values in each host variable file, and Ansible will perform the correct replacement. Thus, we've reduced the side of the play, and extended it to work in more situations.
Handlers
Handlers offer a way to reuse task functionality. In an earlier post, we built a restart_nginx play that checked variable, nginx_conf, to see if it registered a change. If so, then we called the restart Nginx play using a when clause:
when: nginx_conf.changed
This works well, but there may be other reasons to restart our web server that have nothing to do with the configuration file. Without a handler, we would need to write a second restart Nginx play that is called when a different variable registers the change.
To create a handler, we need to start with a directory under the role of our choice called handlers:
playbooks/
roles/
web_servers/
handlers/
main.yml
As you can see, our handler, like our task book is stored in a file called main.yml. The code for our restart Nginx handler is:
- name: restart_nginx
service:
name: "{{ nginx_service_name }}"
state: restarted
Going back to the play that calls the handler, we'll replace the register: nginx_conf line with a notify directive that calls the handler by name:
- name: Enable HTTPS in Nginx
tags: nginx,web
lineinfile:
path: "/etc/nginx/nginx.conf"
line: " listen *:443 ssl;"
insertafter: 'listen 80'
firstmatch: true
backup: true
notify: restart_nginx
The advantage here is that we can call the handler from any code in the web_server role.
No comments:
Post a Comment