Ansible Configuration Management

4 Nov 2026, 11:2822 min readby ITYantra Admin

Complete guide to Ansible configuration management including playbooks, roles, inventory, vault, and best practices for infrastructure automation.

# Ansible Configuration Management

Introduction

Ansible is an open-source automation tool for configuration management, application deployment, and task automation. Ansible uses SSH for communication (no agent required), YAML for playbook definitions, and follows an idempotent model where running the same playbook multiple times produces the same result.

This tutorial covers Ansible installation, inventory management, playbooks, roles, modules, vault encryption, and production best practices.

Learning Objectives

By the end of this tutorial, you will be able to:

  • Install and configure Ansible
  • Manage inventory files and groups
  • Write Ansible playbooks with tasks and modules
  • Create reusable Ansible roles
  • Use Ansible Vault for secrets encryption
  • Implement idempotent configuration management
  • Integrate Ansible with CI/CD pipelines
  • Apply Ansible best practices for production

Technical Background

Ansible Architecture

flowchart LR
    Control[Control Node] -->|SSH/WinRM| Target1[Target 1]
    Control -->|SSH/WinRM| Target2[Target 2]
    Control -->|SSH/WinRM| TargetN[Target N]
    
    Control --> Inventory[Inventory]
    Control --> Playbook[Playbook]
    Control --> Modules[Modules]
    
    subgraph Control Node
    Control
    Inventory
    Playbook
    Modules
    end
    
    subgraph Managed Nodes
    Target1
    Target2
    TargetN
    end

Key Ansible Concepts

| Concept | Description | |---------|-------------| | Control node | Machine where Ansible is installed | | Managed node | Remote machine being configured | | Inventory | List of managed nodes and groups | | Module | Unit of code executed on managed nodes | | Task | Single unit of work (calls a module) | | Playbook | YAML file containing plays and tasks | | Play | Maps hosts to tasks | | Role | Reusable group of tasks, variables, files | | Fact | Information discovered about managed node | | Vault | Encryption for sensitive data |

Idempotency

Ansible tasks are idempotent—running them multiple times produces the same result without side effects. This is achieved by checking the current state before making changes.

Prerequisites

  • Linux control node (Ubuntu, RHEL, or similar)
  • Python 3.8 or later
  • SSH access to managed nodes
  • Sudo privileges on managed nodes
  • Understanding of YAML syntax

Hardware and Software Requirements

| Component | Requirement | |-----------|-------------| | Control Node | Linux with Python 3.8+ | | Managed Nodes | Linux/Windows with SSH/WinRM | | Ansible | Latest stable version | | SSH | Key-based authentication | | Sudo | Passwordless sudo for ansible user |

Step-by-Step Implementation

Phase 1: Install Ansible

# Ubuntu/Debian
sudo apt update
sudo apt install ansible -y

# RHEL/CentOS
sudo yum install ansible -y

# Verify
ansible --version

Phase 2: Configure Inventory

#### Static Inventory

# inventory.ini
[web_servers]
web1.example.com ansible_host=192.168.1.10
web2.example.com ansible_host=192.168.1.11

[db_servers]
db1.example.com ansible_host=192.168.1.20

[load_balancers]
lb1.example.com ansible_host=192.168.1.30

[all:vars]
ansible_user=deploy
ansible_ssh_private_key_file=~/.ssh/id_ed25519
ansible_become=yes
ansible_become_method=sudo

#### Group Variables

# group_vars/web_servers.yml
nginx_port: 80
nginx_worker_processes: auto
web_root: /var/www/html

# group_vars/db_servers.yml
db_port: 5432
db_max_connections: 100
db_version: "15"

#### Host Variables

# host_vars/web1.example.com.yml
ansible_host: 192.168.1.10
custom_setting: web1-specific-value

Phase 3: Write Playbooks

#### Basic Playbook

# playbooks/configure-web.yml
---
- name: Configure Web Servers
  hosts: web_servers
  become: yes
  vars:
    nginx_version: "1.24"
  
  tasks:
    - name: Install Nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: yes
    
    - name: Start and enable Nginx
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: yes
    
    - name: Configure Nginx
      ansible.builtin.template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/default
        owner: root
        group: root
        mode: '0644'
      notify: Restart Nginx
    
    - name: Ensure web root exists
      ansible.builtin.file:
        path: /var/www/html
        state: directory
        owner: www-data
        group: www-data
        mode: '0755'
    
    - name: Deploy index.html
      ansible.builtin.copy:
        src: files/index.html
        dest: /var/www/html/index.html
        owner: www-data
        group: www-data
        mode: '0644'
    
  handlers:
    - name: Restart Nginx
      ansible.builtin.service:
        name: nginx
        state: restarted

#### Run Playbook

# Run playbook
ansible-playbook -i inventory.ini playbooks/configure-web.yml

# Run with syntax check
ansible-playbook -i inventory.ini playbooks/configure-web.yml --syntax-check

# Run in check mode (dry run)
ansible-playbook -i inventory.ini playbooks/configure-web.yml --check

# Run with verbose output
ansible-playbook -i inventory.ini playbooks/configure-web.yml -v

# Run on specific host
ansible-playbook -i inventory.ini playbooks/configure-web.yml --limit web1.example.com

Phase 4: Use Ansible Modules

#### Common Modules

# Package management
- name: Install Apache
  ansible.builtin.apt:
    name: apache2
    state: present

# File management
- name: Create configuration file
  ansible.builtin.copy:
    content: |
      server {
        listen 80;
        server_name example.com;
      }
    dest: /etc/nginx/sites-available/example.com
    owner: root
    group: root
    mode: '0644'

# Service management
- name: Restart Apache
  ansible.builtin.service:
    name: apache2
    state: restarted

# User management
- name: Create deploy user
  ansible.builtin.user:
    name: deploy
    shell: /bin/bash
    groups: sudo
    append: yes

# Command execution
- name: Run custom command
  ansible.builtin.command: /usr/local/bin/health-check.sh
  register: health_result
  changed_when: health_result.rc == 0

# Template with Jinja2
- name: Deploy config with template
  ansible.builtin.template:
    src: templates/myapp.conf.j2
    dest: /etc/myapp/myapp.conf
    vars:
      app_port: 8080
      app_host: "0.0.0.0"

Phase 5: Create Roles

#### Role Structure

roles/
  nginx/
    defaults/
      main.yml
    tasks/
      main.yml
    handlers/
      main.yml
    templates/
      nginx.conf.j2
    files/
      index.html
    vars/
      main.yml
    meta/
      main.yml
    README.md

#### Create Role with ansible-galaxy

# Initialize role
ansible-galaxy role init roles/nginx

# Install role from Galaxy
ansible-galaxy install geerlingguy.nginx

#### Role Tasks

# roles/nginx/tasks/main.yml
---
- name: Install Nginx
  ansible.builtin.apt:
    name: nginx
    state: present
    
- name: Configure Nginx
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: Restart Nginx
  
- name: Start Nginx
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: yes

#### Role Handlers

# roles/nginx/handlers/main.yml
---
- name: Restart Nginx
  ansible.builtin.service:
    name: nginx
    state: restarted

#### Use Role in Playbook

# playbooks/site.yml
---
- name: Configure Web Servers
  hosts: web_servers
  become: yes
  roles:
    - role: nginx
      vars:
        nginx_port: 8080
    
    - role: common
    
    - role: security
      when: ansible_os_family == "Debian"

Phase 6: Ansible Vault for Secrets

#### Encrypt Variables

# Create encrypted file
ansible-vault create group_vars/web_servers/vault.yml

# Edit encrypted file
ansible-vault edit group_vars/web_servers/vault.yml

# Encrypt existing file
ansible-vault encrypt group_vars/web_servers/vault.yml

# Decrypt file
ansible-vault decrypt group_vars/web_servers/vault.yml

# View encrypted file
ansible-vault view group_vars/web_servers/vault.yml

#### Use Vault in Playbook

# group_vars/web_servers/vault.yml
db_password: "super-secret-password"
api_key: "sk-live-1234567890abcdef"
# playbooks/deploy.yml
---
- name: Deploy Application
  hosts: web_servers
  become: yes
  vars_files:
    - group_vars/web_servers/vault.yml
  
  tasks:
    - name: Configure database password
      ansible.builtin.template:
        src: templates/db.conf.j2
        dest: /etc/app/db.conf
        mode: '0600'

#### Run with Vault

# Provide vault password
ansible-playbook -i inventory.ini playbooks/deploy.yml --ask-vault-pass

# Use vault password file
ansible-playbook -i inventory.ini playbooks/deploy.yml --vault-password-file ~/.vault_pass

Phase 7: Ansible Best Practices

#### Project Structure

ansible/
├── ansible.cfg
├── inventory.ini
├── group_vars/
│   ├── all.yml
│   ├── web_servers.yml
│   └── db_servers.yml
├── host_vars/
├── roles/
│   ├── common/
│   ├── nginx/
│   └── postgresql/
├── playbooks/
│   ├── site.yml
│   └── deploy.yml
└── vault/
    └── vault_pass

#### ansible.cfg

[defaults]
inventory = inventory.ini
remote_user = deploy
host_key_checking = False
roles_path = roles
retry_files_enabled = False
stdout_callback = yaml
timeout = 30

[privilege_escalation]
become = yes
become_method = sudo

Expected Output

  • Ansible control node configured and ready
  • Inventory with host and group variables
  • Playbooks for application deployment and configuration
  • Reusable roles for common components
  • Encrypted secrets with Ansible Vault
  • Idempotent configuration management

Verification Procedures

| Check | Method | Expected Result | |-------|--------|-----------------| | Ansible connectivity | `ansible all -m ping` | All hosts reachable | | Playbook syntax | `ansible-playbook --syntax-check` | No syntax errors | | Dry run | `ansible-playbook --check` | Shows changes without applying | | Idempotency | Run playbook twice | Second run reports no changes | | Role execution | Run playbook with roles | All roles applied successfully |

Troubleshooting Scenarios

| Issue | Diagnosis | Resolution | |-------|-----------|------------| | SSH connection failed | SSH key not installed or wrong user | Copy SSH key; verify ansible_user | | Permission denied | Missing sudo privileges | Configure passwordless sudo | | Module not found | Wrong module name or collection | Use FQCN: ansible.builtin.apt | | Template error | Jinja2 syntax error | Fix template syntax | | Vault decryption fails | Wrong vault password | Check vault password file | | Task fails on specific host | Host-specific issue | Use --limit to isolate; check host facts |

Best Practices

  • **Use FQCN:** Always use fully qualified collection names (ansible.builtin.apt)
  • **Keep playbooks idempotent:** Tasks should produce same result on repeated runs
  • **Use roles:** Organize code into reusable roles
  • **Separate variables:** Use group_vars and host_vars instead of hardcoding
  • **Encrypt secrets:** Use Ansible Vault for all sensitive data
  • **Test in check mode:** Always run --check before applying to production
  • **Use handlers:** Restart services only when configuration changes
  • **Document roles:** Include README.md in each role

Security Considerations

  • **Vault encryption:** Encrypt all passwords, API keys, and certificates
  • **Restrict vault access:** Limit who can decrypt vault files
  • **Use SSH keys:** Never use password authentication
  • **Limit sudo:** Configure specific sudo commands for ansible user
  • **Audit playbook changes:** Review changes to playbooks and roles
  • **Secure control node:** Protect the Ansible control node with strong access controls

Conclusion

Ansible provides agentless configuration management with a simple YAML syntax and powerful module library. By following best practices for inventory organization, role design, vault encryption, and idempotency, teams can automate infrastructure configuration reliably and consistently. Ansible's agentless architecture makes it easy to adopt without installing software on managed nodes.

References

  • Ansible Documentation: https://docs.ansible.com/
  • Ansible Galaxy: https://galaxy.ansible.com/
  • Ansible Best Practices: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_best_practices.html
  • Ansible Vault: https://docs.ansible.com/ansible/latest/vault_guide/index.html
  • Ansible Modules: https://docs.ansible.com/ansible/latest/collections/index.html
#idempotent#vault#inventory#roles#playbook#automation#configuration-management#ansible