Ansible is a powerful automation tool that can significantly improve your infrastructure management and application deployment processes. However, to get the most out of Ansible, it’s crucial to follow best practices. This guide will walk you through key best practices and provide practical examples.
1. Directory Structure
A well-organized directory structure is essential for maintaining a scalable Ansible project.
Best Practice:
Use a standard directory layout to organize your Ansible files.
Example:
ansible-project/
├── ansible.cfg
├── inventory/
│ ├── production
│ └── staging
├── group_vars/
│ ├── all.yml
│ └── webservers.yml
├── host_vars/
│ └── web1.example.com.yml
├── roles/
│ ├── common/
│ ├── webserver/
│ └── database/
└── playbooks/
├── site.yml
├── webserver.yml
└── database.yml
2. Use Roles
Roles allow you to organize tasks, variables, and handlers into reusable components.
Best Practice:
Break down your automation tasks into roles for better modularity and reusability.
Example:
Creating a “webserver” role:
roles/webserver/
├── tasks/
│ └── main.yml
├── handlers/
│ └── main.yml
├── templates/
│ └── nginx.conf.j2
└── vars/
└── main.yml
Content of roles/webserver/tasks/main.yml
:
---
- name: Install Nginx
apt:
name: nginx
state: present
- name: Copy Nginx config file
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx
- name: Ensure Nginx is running
service:
name: nginx
state: started
enabled: yes
3. Use Variables
Variables make your playbooks more flexible and reusable across different environments.
Best Practice:
Use group_vars and host_vars to manage variables for different groups of hosts or specific hosts.
Example:
In group_vars/webservers.yml
:
---
nginx_port: 80
nginx_worker_processes: 4
Then in your tasks:
- name: Configure Nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
vars:
port: "{{ nginx_port }}"
worker_processes: "{{ nginx_worker_processes }}"
4. Use Vault for Sensitive Data
Never store passwords or sensitive data in plain text.
Best Practice:
Use Ansible Vault to encrypt sensitive data.
Example:
Encrypting a file:
ansible-vault encrypt group_vars/all/vault.yml
Content of group_vars/all/vault.yml
:
---
db_password: supersecret123
Using the encrypted variable in a playbook:
- name: Configure database
mysql_user:
name: myapp
password: "{{ db_password }}"
Run the playbook with:
ansible-playbook site.yml --ask-vault-pass
5. Use Tags
Tags allow you to run specific parts of a playbook.
Best Practice:
Use tags to categorize and selectively run tasks.
Example:
In your playbook:
- name: Install web server
apt:
name: nginx
state: present
tags:
- webserver
- installation
- name: Start web server
service:
name: nginx
state: started
tags:
- webserver
- service
Run only tasks tagged “webserver”:
ansible-playbook site.yml --tags webserver
6. Use Handlers for Triggering Services
Handlers are tasks that only run when notified by other tasks.
Best Practice:
Use handlers for restarting services or triggering actions that should only happen once, regardless of how many tasks notify them.
Example:
In roles/webserver/handlers/main.yml
:
---
- name: Restart Nginx
service:
name: nginx
state: restarted
In your tasks:
- name: Copy Nginx config file
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx
7. Use Playbook Includes and Imports
For complex deployments, break your playbooks into smaller, manageable files.
Best Practice:
Use include_tasks
for dynamic inclusions and import_playbook
for static imports.
Example:
In site.yml
:
---
- name: Configure webservers
hosts: webservers
roles:
- common
- webserver
- import_playbook: database.yml
8. Use Ansible-lint
Ansible-lint helps maintain consistent style and avoid common pitfalls.
Best Practice:
Run ansible-lint regularly on your playbooks and roles.
Example:
Install ansible-lint:
pip install ansible-lint
Run it on your project:
ansible-lint playbooks/*.yml roles/*
9. Use Version Control
Always keep your Ansible code in version control.
Best Practice:
Use Git to track changes to your Ansible code.
Example:
Initialize a Git repository:
git init
git add .
git commit -m "Initial commit of Ansible code"
10. Test Your Playbooks
Always test your playbooks before running them on production systems.
Best Practice:
Use tools like Molecule for testing roles, and maintain a staging environment that mirrors production.
Example:
Initialize a Molecule test for a role:
cd roles/webserver
molecule init scenario -r webserver -d docker
This creates a basic test setup for your webserver role using Docker.
By following these best practices and examples, you can create more maintainable, efficient, and reliable Ansible playbooks. Remember, the key to successful Ansible usage is consistency, modularity, and thorough testing.