Image
5 ways to make your Ansible modules work faster
Optimize how you use Ansible modules to speed up your playbooks.
Ansible is a powerful open source tool that helps you automate many of your IT infrastructure operations, from the smallest of tasks to the largest. Ansible has hundreds of modules to help you accomplish your configuration needs, both official and community-developed. When it comes to complex and lengthy workflows, though, you need to consider how to optimize the way you use these modules so you can speed up your playbooks.
Previously, I wrote about making your Ansible playbooks run faster. Here are five ways I make my Ansible modules work faster for me.
[ New to automation or looking to boost your skills? Sign up for the free online Ansible Basics course. ]
1. Use multiple tasks in a single module and avoid module loops
It's easy to fall into linear thinking. For instance, you might want to install several packages, so you might think to do this in a terminal:
# Multiple `dnf` commands
$ sudo dnf install httpd
$ sudo dnf install firewalld
$ sudo dnf install git
But you can do the same thing more efficiently:
$ sudo dnf install -y httpd firewalld git
The same strategy applies to Ansible playbooks. Instead of installing packages using multiple yum
or dnf
modules, you can pass multiple packages to a single yum
task.
This might be your old method:
- name: Install httpd
ansible.builtin.yum:
name: httpd
- name: Install firewalld
ansible.builtin.yum:
name: firewalld
- name: Install git
ansible.builtin.yum:
name: git
Or maybe you did this:
- name: Install Pacakages
ansible.builtin.yum:
name: "{{ item }}"
state: latest
loop:
- httpd
- firewalld
- git
But the better and more efficient method is this:
- name: Install httpd and firewalld
ansible.builtin.yum:
name:
- httpd
- firewalld
- git
state: latest
2. Avoid copy loops and use the synchronize module
When you have multiple files to copy into the same directory, synchronize
modules rather than using multiple copy
modules or loops:
- name: Copy application data
synchronize:
src: app_data/
dest: /opt/web_app/data
3. Use the latest version of Ansible and its modules
Most of the time, new versions of Ansible include performance and optimization improvements. If possible, use the latest compatible version of Ansible for your environments to ensure you're getting the most recent features. Also, update your modules and roles or Ansible collections to get the current features and bug fixes.
Make sure you've tested the latest version of the module and Ansible before pushing to production and critical environments to avoid breaking any existing functionalities.
[ Get the latest on Red Hat Ansible Automation Platform 2 in this interactive guide. ]
4. Make configuration templates
You might use multiple lineinfile
and blockinfile
tasks to manage and configure a single file. This approach creates a very long playbook. And when there's configuration drift, you must edit this lineinfile
task with a different regex. However, you can use a Jinja2 template to create any level of complex files and use the template
module (or filter) to configure managed nodes.
For instance, you can copy a complex Nginx web server configuration using the template
module with a Jinja2 template.
Your Jinja2 template: nginxd.conf.j2
# nginx configuration for wp-test
server {
root /var/www/{{ website_root_dir }};
index index.php index.html index.htm;
server_name {{ website_name }}.com www.{{ website_name }}.com;
access_log /var/log/nginx/access_{{ website_name }}-com.log;
error_log /var/log/nginx/error_{{ website_name }}-com.log;
...<output removed>...
ssl_certificate /etc/letsencrypt/live/{{ website_name }}.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/{{ website_name }}.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.{{ website_name }}.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
...<output removed>...
server_name {{ website_name }}.com www.{{ website_name }}.com;
return 404; # managed by Certbot
}
The template
module replaces the variable (the code {{ website_root_dir }}
) with values provided in your playbook:
---
- name: Configure the nginx Web Server
hosts: web_servers
become: True
vars:
website_name: myawesomeblog
website_root_dir: /var/www/myawesomeblogdata
tasks:
- name: Copy nginx configuration
template:
src: nginxd.conf.j2
dest: /etc/nginx/sites-enabled/{{ website_name }}.conf
5. Use appropriate modules and avoid using shell or command modules
You can use Ansible shell or command modules to run basic Linux commands. It is highly recommended that you use appropriate modules and use these shell/command
modules in the worst-case scenarios. The shell
(or command
) modules will simply execute the command without any validations, and most of the time, you need to take care of idempotency and error checks.
For example, the first task below (with shell
) simply overwrites the file's content without checking or validating, but the second task (with the copy
module) changes the file only if required, and it also updates the permissions and ownership of the destination file.
- name: Create file using shell module
shell: 'echo "Hello" > /tmp/foo.conf'
- name: Create file with permission using file module
ansible.builtin.copy:
content: "Hello"
dest: /tmp/foo.conf
owner: root
group: root
mode: '0644'
Bonus: Optimize your syntax
Using appropriate modules and module arguments in your playbook saves a lot of time and avoids complications. Refer to the latest module documentation, whether it's in the official Ansible docs or elsewhere, to ensure that the keys and values you remember from the last time you used the module are still valid.
Optimization is a journey
The modules you select and how you use them can affect the global execution time of your Ansible playbooks. But that means each module is an opportunity to optimize your playbook, refine the process, and maximize automation speed.
This isn't a complete list, of course. You can use many other parameters to control and optimize your Ansible playbook execution, such as serial
, throttle
, run_once
, and more. Refer to the documentation to learn more and apply optimization techniques based on your Ansible environment.
Image
Here's how to optimize your Ansible playbooks to make them run faster.
Image
Whether you're new to Ansible or looking to level up your automation skills, you'll find something of value in 2021's top Ansible articles.
Image
Consider these lessons the next time you're automating container tasks with Ansible.
Gineesh Madapparambath
Gineesh Madapparambath is a Platform & DevOps Consultant at Red Hat Singapore, specializing in automation and containerization with Ansible and OpenShift. More about me