Best Practices for Ansible: Making Automated Operations More Elegant and Efficient

Best Practices for Ansible: Making Automated Operations More Elegant and Efficient

> Master these tips to say goodbye to chaotic Playbooks

Introduction: Why Do We Need Best Practices?

Hello everyone, I believe many of you have experienced this when using Ansible: as you write your Playbook, it turns into a tangled mess, and two months later, you can’t even understand what you wrote; or during team collaboration, everyone’s writing style is wildly different, making maintenance a nightmare.

Don’t worry, today I will share some valuable insights on Ansible best practices to make your automated operations both elegant and efficient!

1. Standardizing Directory Structure

Recommended Project Structure

production/  # Production environment inventory file
staging/  # Staging environment inventory file
group_vars/  # Group variables
group1.yml
group2.yml
host_vars/  # Host variables
hostname1.yml
hostname2.yml
library/  # Custom modules
filter_plugins/  # Custom filter plugins
roles/  # Roles directory
common/  # Common roles
webservers/  # Web server roles
databases/  # Database roles
site.yml  # Main Playbook
webservers.yml  # Web service specific Playbook
databases.yml  # Database specific Playbook

Key Reminder: A good directory structure is the foundation of team collaboration, and it is recommended to create each new project according to this standard.

2. The Art of Using Roles

Why Use Roles?

Roles can break down complex Playbooks into reusable components, making it as easy as building with blocks. For example:

Poor Practice: Writing All Tasks in One Playbook

name: Configure Web Server
hosts: webservers
tasks:
  - name: Install nginx
    apt: name=nginx state=present
  - name: Configure nginx
    template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
# ... dozens of other tasks

Good Practice: Using Roles

name: Configure Web Server
hosts: webservers
roles:
  - common
  - nginx
  - monitoring

Standard Structure of Roles

roles/common/tasks/main.yml
handlers/main.yml
templates/nginx.conf.j2
defaults/main.yml
vars/main.yml
meta/main.yml

Practical Tip: Each role should only be responsible for a specific function, adhering to the single responsibility principle.

3. The Wisdom of Variable Management

Variable Priority Usage Guide

Ansible has 22 variable priorities, but remembering these key points is sufficient:

  • Role Default Variables (defaults/main.yml): Provides default values, easiest to override
  • Inventory Variables (inventory vars): Settings for specific hosts or groups
  • Playbook Variables (vars:): Variables defined in the Playbook
  • Extra Variables (-e): Passed via command line, highest priority
  • Safely Managing Sensitive Information

    Never store sensitive information like passwords in plain text in Playbooks! It is recommended to use Ansible Vault:

Encrypting Files

ansible-vault encrypt secrets.yml

Running Playbooks with Encrypted Files

ansible-playbook site.yml --ask-vault-pass

4. Tips for Efficient Task Writing

Using Complete Parameters for Modules

Discouraged Practice

apt: name={{ item }} state=present
with_items:
  - nginx
  - curl

Recommended Practice

name: Install Necessary Packages
apt:
  name: "{{ packages }}"
  state: present
  update_cache: yes
vars:
  packages:
    - nginx
    - curl

Proper Use of Handlers

Handlers are suitable for restarting services after configuration changes, but should not be overused:

Defining Handlers in Roles

roles/nginx/handlers/main.yml

name: restart nginx
service:
  name: nginx
  state: restarted

Notifying Handlers in Tasks

name: Configure nginx
template:
  src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: restart nginx
  • 5. Performance Optimization Suggestions

    Enable Pipelining

    Enable in ansible.cfg:

    ini
    [ssh_connection]
    pipelining = True
  • This can reduce the number of SSH connections and significantly improve execution speed.

    Using Asynchronous Tasks

    For long-running tasks:

    name: Long Running Task
    command: /path/to/long_running_operation.sh
    async: 3600  # Timeout (seconds)
    poll: 0  # No need to wait for completion
    name: Check Asynchronous Task Status
    async_status: jid="{{ ansible_job_id }}"
    register: job_result
    until: job_result.finished
    retries: 30
  • Conclusion: Practice Leads to Mastery

    The core idea of Ansible best practices is: Readability, Maintainability, Reusability. Remember these principles:

    🎯 Keep it simple and clear

    🎯 Use roles to break down complex logic

    🎯 Safely manage sensitive information

    🎯 Continuously optimize performance

    The best practices are those that are continuously summarized and adjusted in real projects. I hope today’s sharing helps everyone navigate the use of Ansible more smoothly!

    If you have better practice insights, feel free to share and discuss in the comments!

Leave a Comment