Wednesday, April 23, 2025

Ansible Journey 7: Improving Your Playbook

 

In this section, we will take the playbook containing six individual plays and consolidate down to just a single play. There are pros and cons to doing this which will be reviewed at the end. There are a number of things we can do to may this playbook shorter; each using a different method.

In the first case, we can eliminate two of the plays by combining the package install plays. both apt and dnf modules allow us to specify more than one package. This is accomplished by turning the name parameter into a list, then specifying each package as a member of the list. The two name lines specified in the dnf plays:

 

name: nginx

name: pcp-pmda-nginx

 

become

 

name:

- nginx

- pcp-pmda-nginx

 

 With that, we can remove one of the dnf modules for a package. Likewise, for apt:


name: nginx-core

name: nginx-doc


become


name:

- nginx-core

- nginx-doc


We have thus reduced the number of plays by 30%.

At this point, I should call out something I did that differs from the author of the videos. I selected two different packages as the second package in each play: Performance Co-Pilot in one and Nginx documentation in the other. Normally, we would stick to the equivalent packages common across both distributions. I started with Rocky Linux and Nginx (the author started with Ubuntu and Apache packages) and the packages available for Nginx do not line up the way Apache packages do across distributions. While it comes across rather odd, the principle is the same.

The second update is to make updating the cache part of the package installation play. This is possible because (as mentioned earlier) both dnf and app modules use the “update_cache” parameter. Since update_cache is a parameter available in both modules, we add it underneath the module name, similar to the state parameter:


- name: Install Nginx Web Service

  dnf:

  name:

    - nginx

    - pcp-pmda-nginx

  state: latest

  update_cache: true

  when: ansible_distribution == "Rocky"


Once done with the apt module, we have reduced the number of plays further down to just 2.

Finally, we consolidate the plays into one. In order for that to work, we need to introduce variables. Variables can be identical across hosts, or they can change from host to host. Following is the format of a variable when used in a play:


{{ variable_name }}


Because there are spaces in between the curly braces and the variable name, we include the entire thing in quotes.

When declared, variables use a simple space-separated set of key/value pairs. These are stored in the inventory file as:

 

hostname_or_ip variable_name_1=value_1 variable_name_2=value_2…


Specifying these in our inventory file becomes:


192.168.5.250 nginx_package=nginx extra_package=pcp-pmda-nginx

192.168.5.251 nginx_package=nginx extra_package=pcp-pmda-nginx

192.168.6.30 nginx_package=nginx-core extra_package=nginx-doc


Since we are specifying the packages per host, and each host can only contain one distrubution, we can eliminate the when clauses we added in the prior post. Then, we replace the package names in our play with their corresponding variables:


- name: Install Nginx Web Service

  package:

  name:

    - "{{ nginx_package }}"

    - "{{ extra_package }}"

  state: latest

  update_cache: true


You’ll notice one additional change was made: we replaced dnf: and apt: with package:. The package module is a generalized package module that arranges with each host what the host uses as a package manager. So, selecting the package manager is now Ansible’s responsibility.


Pros and Cons of Consolidation

Pros:

Through consolidation, our play ends up running slightly faster. This won’t be very apparent in such a simple playbook, but at scale will make a noticeable difference.

The playbook is shorter (with respect to the number of lines), and fewer plays. If we are reviewing the playbook for high-level functionality (we see what it’s doing, but not so much how), we can understand more quickly what is happening.

Cons:

When consolidating plays, we are executing the same amount of work with fewer directives. This means we are hiding some of the details. (Well, not so much hiding, as shifting some of those details to other areas, such as our inventory file.) That can make a playbook harder to read.

The name of each play is printed in the output, followed by the results. When we had six plays, we were able to see the result of each individual play. Having consolidated the plays into one, we see just the single play in the output (See Figure 7.1). If there is a failure, more work will be required to discern exactly where the failure occurred and why.

Figure 7.1: Running multiple actions using a single play.

 

Ultimately, as sysadmins, we will need to make a choice that balances ease of reading and troubleshooting with concise code.

 

<PREV - CONTENTS - NEXT>

No comments:

Post a Comment