YAML in Ansible: Mastering Automation

Learn how to effectively use YAML in Ansible for automation. From basic playbooks to advanced configurations, master the art of infrastructure as code.

12 min read

Ansible YAML Fundamentals

Playbook Structure

---
- name: Basic Playbook
  hosts: web_servers
  become: true
  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present

Key Components

  • Plays and Tasks
  • Variables and Facts
  • Handlers and Roles

Advanced Concepts

Variables and Templates

---
- name: Configure Web Server
  hosts: web_servers
  vars:
    http_port: 80
    domain: example.com
  tasks:
    - name: Generate nginx config
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/sites-available/default
      vars:
        server_name: "{{ domain }}"

Roles Structure

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

Best Practices

1

Use Meaningful Names

Give tasks and plays descriptive names for better readability

2

Organize with Roles

Break down complex playbooks into reusable roles

3

Version Control

Keep playbooks in version control with proper documentation

4

Validate Playbooks

Use ansible-lint to check for best practices and potential issues

5

Use Variables Wisely

Leverage group_vars and host_vars for better organization

Common Patterns

Conditional Tasks

- name: Install packages based on OS
  package:
    name: "{{ item }}"
    state: present
  when: ansible_os_family == 'Debian'
  loop:
    - nginx
    - postgresql
    - python3

Handlers

tasks:
  - name: Copy nginx config
    template:
      src: nginx.conf.j2
      dest: /etc/nginx/nginx.conf
    notify: Restart nginx

handlers:
  - name: Restart nginx
    service:
      name: nginx
      state: restarted

Security Best Practices

Vault Integration

Use ansible-vault for sensitive data encryption

Privilege Escalation

Use 'become' carefully and only when necessary

SSH Management

Use SSH keys and proper key management

Module Security

Use secure modules and verify module sources

Common Pitfalls

YAML Indentation

Problem: Incorrect indentation breaking playbook structure

Solution: Use consistent 2-space indentation and YAML validators

Variable Precedence

Problem: Confusion about variable override order

Solution: Understand and document variable precedence rules

Task Idempotency

Problem: Tasks that are not idempotent

Solution: Design tasks to be idempotent and use proper state checking

Role Dependencies

Problem: Complex role dependencies leading to conflicts

Solution: Keep role dependencies minimal and well-documented

Validate Your Ansible YAML

Use our free tools to validate and format your Ansible playbooks.

Additional Resources

Practical Examples

Web Server Setup

---
- name: Configure Web Server
  hosts: web_servers
  become: true
  vars:
    domain: example.com
    web_root: /var/www/html

  tasks:
    - name: Install required packages
      apt:
        name: 
          - nginx
          - certbot
        state: present
        update_cache: yes

    - name: Create web root directory
      file:
        path: "{{ web_root }}"
        state: directory
        mode: '0755'

    - name: Configure nginx virtual host
      template:
        src: vhost.conf.j2
        dest: /etc/nginx/sites-available/{{ domain }}
      notify: Restart nginx

  handlers:
    - name: Restart nginx
      service:
        name: nginx
        state: restarted

Database Backup Role

---
- name: Database Backup Role
  hosts: db_servers
  become: true
  vars:
    backup_dir: /var/backups/postgres
    retention_days: 7

  tasks:
    - name: Ensure backup directory exists
      file:
        path: "{{ backup_dir }}"
        state: directory
        mode: '0750'
        owner: postgres

    - name: Create backup script
      template:
        src: backup.sh.j2
        dest: /usr/local/bin/db-backup
        mode: '0755'

    - name: Setup backup cron job
      cron:
        name: "Database backup"
        hour: "3"
        minute: "0"
        job: "/usr/local/bin/db-backup"

    - name: Setup backup rotation
      cron:
        name: "Cleanup old backups"
        hour: "4"
        minute: "0"
        job: "find {{ backup_dir }} -type f -mtime +{{ retention_days }} -delete"

Version Control Integration

Repository Structure

ansible-project/
├── inventories/
│   ├── production/
│   │   ├── hosts
│   │   ├── group_vars/
│   │   └── host_vars/
│   └── staging/
├── roles/
│   ├── common/
│   ├── webserver/
│   └── database/
├── playbooks/
│   ├── site.yml
│   ├── webserver.yml
│   └── database.yml
├── requirements.yml
└── ansible.cfg

Version Control Best Practices

  • Keep sensitive data encrypted with ansible-vault
  • Use meaningful commit messages
  • Tag releases for production deployments
  • Include proper .gitignore file
  • Document dependencies in requirements.yml

Testing & Validation

Syntax Check

# Check playbook syntax
ansible-playbook --syntax-check playbook.yml

# Dry run
ansible-playbook -C playbook.yml

# Validate with ansible-lint
ansible-lint playbook.yml

Molecule Testing

# Initialize Molecule test environment
molecule init role my-role

# Run tests
molecule test

# Test specific scenario
molecule test -s custom-scenario