In this tutorial, we'll explain what is the Ansible best practices for writing clean playbooks that covers best practices, structuring techniques, and tools like ansible-lint for enforcing standards. This guide is structured to provide deep insights, ensuring your audience can learn effectively and apply it to their Ansible playbooks.
Ansible is a powerful automation tool that helps streamline infrastructure management. However, writing Ansible playbooks that are maintainable, readable, and efficient requires following certain best practices. This guide will provide a deep dive into writing clean playbooks, structuring them for maintainability, using roles, tags, and includes, and leveraging ansible-lint for quality assurance.
Ansible Best Practices for Writing Clean Playbooks
1. Structuring Playbooks for Readability and Maintainability
a. Use YAML Best Practices
Ansible playbooks are written in YAML, so adhering to YAML best practices is crucial:
Use 2
spaces for indentation. Avoid tabs, as YAML is whitespace-sensitive.
Clearly define your hosts
, vars
, and tasks
.
Use -
consistently for lists, such as task definitions.
Example:
---
- name: Ensure the web server is installed and running
hosts: webservers
become: true
tasks:
- name: Install Nginx
ansible.builtin.yum:
name: nginx
state: present
- name: Start Nginx service
ansible.builtin.service:
name: nginx
state: started
b. Use Descriptive Names
Each playbook, play, and task should have clear, descriptive names:
- Avoid generic names like "Install software." Instead, be specific: "Install and start Nginx web server."
- This makes troubleshooting easier when you read through logs or playbook outputs.
c. Organize Variables
Variables should be structured to maintain clarity:
- Use a vars directory or file to manage variables centrally.
- Use
group_vars
andhost_vars
for group-specific or host-specific configurations. - Keep sensitive variables in encrypted vault files using
ansible-vault
.
d. Use Comments Generously
Well-placed comments explain why a task is performed, not just what it does. Add comments to complex parts of the playbook to help future maintainers understand your logic.
e. Use Conditionals and Loops Wisely
Ansible allows you to use conditionals and loops. Use these features to avoid redundant tasks, but don’t overcomplicate the playbook:
- Use when conditions to make tasks conditional.
- Use
with_items
or loop to iterate over items.
Example:
- name: Install multiple packages
ansible.builtin.yum:
name: "{{ item }}"
state: latest
loop:
- httpd
- php
- mariadb-server
when: ansible_os_family == "RedHat"
2. Using Roles, Tags, and Includes to Organize Playbooks
a. Using Roles for Better Structure
Roles are a key component of organizing Ansible playbooks. They provide a modular structure:
A role can contain tasks, handlers, variables, templates, and files related to a specific functionality.
Use the ansible-galaxy init <role_name>
command to create a skeleton for a role.
Each role should have a specific purpose, such as installing Nginx, configuring a firewall, or deploying an application.
Role Directory Structure:
my_role/
├── defaults/
│ └── main.yml
├── files/
├── handlers/
│ └── main.yml
├── tasks/
│ └── main.yml
├── templates/
├── vars/
│ └── main.yml
└── meta/
└── main.yml
b. Using Tags for Task Selection
Tags allow you to run specific parts of a playbook without executing the entire playbook:
- Use tags to categorize tasks by their function or purpose, such as setup, deploy, configure, etc.
- Use the
--tags
option to run a playbook with specific tags or--skip-tags
to exclude tasks.
Example with Tags:
tasks:
- name: Install Apache
ansible.builtin.yum:
name: httpd
state: present
tags: install
- name: Start Apache service
ansible.builtin.service:
name: httpd
state: started
tags: config
Command to Run Tagged Tasks:
ansible-playbook site.yml --tags "install"
c. Using Includes and Imports for Readability
To split large playbooks into smaller, more manageable pieces, use includes or imports:
- include_tasks dynamically includes tasks at runtime.
- import_tasks statically includes tasks during the playbook parsing phase.
- include_vars to include variables from external files.
Example of Task Inclusion:
- name: Configure Web Server
import_tasks: tasks/webserver.yml
- name: Install Database
include_tasks: tasks/database.yml
3. Tips for Using ansible-lint to Enforce Best Practices
ansible-lint is a tool that enforces Ansible playbook best practices. It provides feedback on syntax errors, security risks, and style violations.
a. Install ansible-lint
You can install ansible-lint using pip:
pip install ansible-lint
b. Use a .ansible-lint Configuration File
To customize the behavior of ansible-lint
, create a .ansible-lint configuration file in your project directory:
---
skip_list:
- '403' # Skip specific rule by ID
warn_list:
- '106' # Warnings for rules
rulesdir: ~/.config/ansible-lint/rules
c. Run ansible-lint Against Playbooks
Execute ansible-lint to check your playbooks for best practices and errors:
ansible-lint playbook.yml
Review and resolve any issues reported. Some key areas ansible-lint covers:
- Indentation issues.
- Task names must be unique.
- Unused or undefined variables.
- Deprecated modules or parameters.
- Unquoted when conditions.
d. Custom Lint Rules
You can add custom rules to suit your project’s needs. Create a directory for custom rules and reference it in your .ansible-lint
file. Each rule is a Python script that extends Ansible’s linting capabilities.
e. Integrating ansible-lint in CI/CD Pipelines
Integrate ansible-lint into your Continuous Integration (CI) pipeline to enforce quality checks:
Use tools like GitHub Actions, GitLab CI, or Jenkins to automatically run ansible-lint
on pull requests.
- This ensures playbook quality without manual reviews.
- Summary of Key Best Practices
- Use YAML best practices for clarity.
- Leverage roles to modularize playbooks.
- Use tags for targeted playbook execution.
- Split complex playbooks with includes and imports.
- Use ansible-lint to enforce quality standards.
- Comment your code generously and use meaningful task names.
By following these guidelines, you'll write cleaner, more maintainable Ansible playbooks that are easier for teams to manage and scale.
Checkout our dedicated servers India, Instant KVM VPS, and Web Hosting India