Ansible is designed to be minimal, consistent, secure, and highly reliable, with an extremely low learning curve for administrators, developers, and IT managers. In other words, Ansible should be easy to work with, but there are still some ways of using it that are better than others.
[ Download now: A system administrator's guide to IT automation. ]
Whether you're writing playbooks, maintaining inventory, or executing tasks, here are 10 things to keep in mind as you implement enterprise-wide automation:
- Use version control
- Use whitespace and comments
- Give variables unique and meaningful names
- Use roles to keep playbooks well-organized
- Troubleshoot on execution
- Use block syntax
- Use a separate inventory file for staging and production
- Understand the serial keyword for rolling updates
- Use native modules when possible
- Keep debugging messages clean
This article is a combination of advice pulled from official Ansible documentation and two presentations by Ansible experts: Ansible best practices: the essentials and Ansible best practices: How to write, how to execute, and how to use in real life). You don't need to treat them as gospel. Some of these practices may not fit your specific use case, and that's okay! If nothing else, you'll have a solid baseline of Ansible knowledge from which to build your skills.
1. Use version control
Using version control is a standard practice when coding, and Ansible is no different. Be sure to keep playbooks, roles, inventory, and variables files in Git or another version control system, and make commits often.
2. Use whitespace and comments
Ansible uses YAML for writing playbooks, and whitespace characters (literal space characters) are what YAML uses to define document structure and denote nesting. Tabs are not allowed.
For example:
foo: bar
dah: dum
lah:
dee: dah
dah: dee
is translated into Python (using the PyYAML library) as:
foo : bar
dah : dum
lah : {'dee': 'dah', 'dah': 'dee'}
Using comments is another best practice that can help you meaningfully describe lines of code. Don't overuse them—the more clear the comment, the better! In YAML, comments begin with a pound (or hash) sign:
# This is a comment
[ Want to learn more? Start the Ansible Basics: Automation technical overview course. ]
3. Give variables unique and meaningful names
Add the role name to a variable as a prefix to avoid name conflicts and confusion.
For example:
apache_max_keepalive: 25
apache_port: 80
tomcat_port: 8080
Instead of:
max_keepalive: 25
port: 80
port: 8080
[ Check out a personalized skill path for becoming a Red Hat Certified Specialist in Ansible Network Automation. ]
4. Use roles to keep playbooks well-organized
While there are many possible ways to organize playbook content, one crucial way is with Ansible’s roles organization feature. Here is an example role directory structure:
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
5. Troubleshoot on execution
If you're looking to test new plays or do some debugging, there are a few alternative ways to run playbooks in Ansible. Using these switches can help you catch problems in your code more quickly. Here is a breakdown of a few:
-vvvv
enables connection debugging.--step
causes Ansible to stop on each task and ask if it should execute that task.--check
enables check mode, where Ansible runs without making any changes on remote systems.--diff
enables diff mode, where Ansible provides before-and-after comparisons.--start-at-task
starts executing your playbook at a particular task.
6. Use block syntax
You can use Ansible blocks to group tasks logically. Blocks make it much easier to set data or directives common to a bunch of tasks, organize code, and enable rollbacks for critical changes.
Tasks:
- name: Install, configure, and start Apache
block:
- name: install httpd and memcached
yum:
name:
- httpd
- memcached
state: present
- name: apply the foo config template
template:
src: templates/src.j2
dest: /etc/foo.conf
- name: start service bar and enable it
service:
name: bar
state: started
enabled: True
when: ansible_facts['distribution'] == 'CentOS'
become: true
become_user: root
ignore_errors: yes
ignore_errors: yes
7. Use a separate inventory file for staging and production
You don't want to run a play on a group of servers only to realize a day later that you've just pushed experimental changes into production. To avoid these sorts of surprises, use separate inventory files for staging and production instead of maintaining everything in a single inventory file. For example:
|----inventories/
| |--dev/
| | |--group_vars/...
| | |--host_vars/...
| |--prod/
| |--group_vars/...
| |--host_vars/
| |--my_playbook_hostname_vars.yml
|----roles/...
|----hosts.yml
|----my_playbook.yml
|
8. Understand the serial keyword for rolling updates
You can control how many machines you update at once in the batch with the serial keyword. By default, Ansible tries to manage all the devices referenced in a play in parallel. For a rolling update use case, you can define how many hosts Ansible should manage at a single time by using the serial keyword:
---
- name: test play
hosts: webservers
serial: 2
gather_facts: False
tasks:
- name: task one
command: hostname
- name: task two
command: hostname
9. Use native modules when possible
Ansible's goal is to make things as easy and convenient as possible. So while you can use commands such as command
, shell
, raw
, and script
to do command-line operations, using them excessively could lead to problems down the line. It's best to use run commands sparingly since there are hundreds of native Ansible modules that can do what you need.
[ Explore Red Hat Enterprise Linux Automation with the Ansible training course. ]
10. Keep debugging messages clean
While useful for debugging variables or expressions, the debug module can clutter the output. It's best practice to remove these lines of code before your playbook goes into production. You can also control when the debug is run with a verbosity parameter. For example, if you set it to 3
, it will only run debug when you run -vvv
.
- debug:
msg: "I always display!"
- debug:
msg: "I only display with ansible-playbook -vvv+"
verbosity: 3
Learn more
Ansible enables users across an organization to create, share, and manage automation, but like any tool, some ways of using it are better than others.
If you're looking for further Ansible expertise, check out the resources below.
About the author
Bill Cozens is a recent UNC-Chapel Hill grad interning as an Associate Blog Editor for the Red Hat Blog.
Browse by channel
Automation
The latest on IT automation for tech, teams, and environments
Artificial intelligence
Updates on the platforms that free customers to run AI workloads anywhere
Open hybrid cloud
Explore how we build a more flexible future with hybrid cloud
Security
The latest on how we reduce risks across environments and technologies
Edge computing
Updates on the platforms that simplify operations at the edge
Infrastructure
The latest on the world’s leading enterprise Linux platform
Applications
Inside our solutions to the toughest application challenges
Original shows
Entertaining stories from the makers and leaders in enterprise tech
Products
- Red Hat Enterprise Linux
- Red Hat OpenShift
- Red Hat Ansible Automation Platform
- Cloud services
- See all products
Tools
- Training and certification
- My account
- Customer support
- Developer resources
- Find a partner
- Red Hat Ecosystem Catalog
- Red Hat value calculator
- Documentation
Try, buy, & sell
Communicate
About Red Hat
We’re the world’s leading provider of enterprise open source solutions—including Linux, cloud, container, and Kubernetes. We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.
Select a language
Red Hat legal and privacy links
- About Red Hat
- Jobs
- Events
- Locations
- Contact Red Hat
- Red Hat Blog
- Diversity, equity, and inclusion
- Cool Stuff Store
- Red Hat Summit