Ansible Beginner to Advanced: Complete Automation Guide
📅 Published: August 2026
⏱️ Estimated Reading Time: 16 minutes
🏷️ Tags: Ansible, Automation, Configuration Management, DevOps, Infrastructure as Code
Introduction: What is Ansible?
Ansible is an open-source IT automation engine that automates cloud provisioning, configuration management, application deployment, and intra-service orchestration . Unlike many other automation tools, Ansible is agentless—it does not require any software installed on the machines it manages .
Think of Ansible as a remote control for your infrastructure. You write simple instructions in YAML, and Ansible executes them over SSH (or WinRM for Windows) . Your instructions are "playbooks," and the actions are "tasks" performed by "modules."
Why Ansible stands out:
Agentless: No daemons to install or maintain on target servers
Idempotent: Run the same playbook multiple times, get the same result
Push-based: You control when changes are applied
Large ecosystem: Over 3,000 modules for cloud providers, databases, networking, and more
Part 1: Ansible Architecture
Core Components
┌─────────────────────────────────────────────────────────────────────────────┐ │ Control Node │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ ansible-playbook │ │ │ │ │ │ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ │ │ Playbook │ │ Inventory │ │ Variables │ │ Roles │ │ │ │ │ │ (YAML) │───▶│ File │───▶│ (host_vars,│───▶│(Reusable) │ │ │ │ │ └───────────┘ └───────────┘ │ group_vars)│ └───────────┘ │ │ │ │ ┌───────────┐ └───────────┘ │ │ │ │ │ Modules │ │ │ │ │ │(Plugins) │ │ │ │ │ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ SSH / WinRM │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ Managed Nodes │ │ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ │ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ Node 4 │ │ │ │ │ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘
Key Terms
Part 2: Installation and Setup
Installing Ansible on Ubuntu
# Update package index and install software-properties-common sudo apt update sudo apt install -y software-properties-common # Add the official Ansible PPA sudo add-apt-repository --yes --update ppa:ansible/ansible # Install Ansible sudo apt install -y ansible # Verify installation ansible --version
Installing on CentOS/RHEL
# Enable EPEL repository sudo dnf install -y epel-release # Install Ansible sudo dnf install -y ansible
Installing on macOS
# Install via Homebrew brew install ansible
Configuring Ansible
Create an ansible.cfg file in your project directory:
[defaults] # Path to inventory file inventory = ./inventory/hosts.ini # SSH private key for authentication private_key_file = ~/.ssh/ansible_key # Remote user for SSH connections remote_user = deploy # Disable host key checking for dynamic environments host_key_checking = False # Number of parallel processes forks = 20 # Timeout for SSH connections timeout = 30 # Path to roles roles_path = ./roles [privilege_escalation] # Use sudo for tasks requiring root become = True become_method = sudo become_user = root become_ask_pass = False [ssh_connection] # Use SSH pipelining for better performance pipelining = True
Setting Up SSH Authentication
# Generate an SSH key pair for Ansible ssh-keygen -t ed25519 -C "ansible@control-node" -f ~/.ssh/ansible_key # Copy the public key to managed nodes ssh-copy-id -i ~/.ssh/ansible_key.pub deploy@192.168.1.10
Part 3: Inventory Management
Ansible uses an inventory file to define the machines it manages .
Static Inventory (INI format)
# inventory/hosts.ini [webservers] webserver1.example.com webserver2.example.com [dbservers] db0.example.com [production:children] webservers dbservers [staging] staging-web.example.com
Static Inventory (YAML format)
# inventory/hosts.yml all: children: webservers: hosts: webserver1.example.com: webserver2.example.com: dbservers: hosts: db0.example.com: production: children: - webservers - dbservers
Dynamic Inventory
Ansible can pull inventory from cloud providers like AWS, GCP, and Azure .
# aws_ec2.yml plugin: amazon.aws.aws_ec2 regions: - us-west-2 keyed_groups: - key: tags.Environment prefix: env
Inventory Variables
[webservers] webserver1.example.com ansible_user=admin webserver2.example.com ansible_user=admin [webservers:vars] ansible_port=22 http_port=80
Part 4: Ad-Hoc Commands
Ansible can run one-off commands without playbooks.
# Ping all hosts ansible all -i inventory/hosts.ini -m ping # Check uptime on webservers ansible webservers -i inventory/hosts.ini -a "uptime" # Install a package ansible webservers -i inventory/hosts.ini -m apt -a "name=nginx state=present" --become # Restart a service ansible webservers -i inventory/hosts.ini -m service -a "name=nginx state=restarted" --become
Part 5: Playbooks
Playbooks are YAML files that define automation steps .
Basic Playbook Structure
--- - hosts: webservers become: yes tasks: - name: Install Nginx apt: name: nginx state: present - name: Start Nginx service: name: nginx state: started enabled: yes - name: Copy configuration copy: src: ./nginx.conf dest: /etc/nginx/nginx.conf notify: restart nginx handlers: - name: restart nginx service: name: nginx state: restarted
Running a Playbook
ansible-playbook -i inventory/hosts.ini site.ymlPlaybook Components
Part 6: Variables and Facts
Variables
--- - hosts: webservers vars: app_port: 8080 app_user: webapp tasks: - name: Create app user user: name: "{{ app_user }}" - name: Start app on port {{ app_port }} shell: "python app.py --port {{ app_port }}"
Variable Precedence
Variables can be defined in multiple places (from highest to lowest precedence):
Command-line
--extra-varsHost variables in inventory
Group variables in inventory
Playbook variables
Role defaults
Facts
Ansible gathers system information (facts) from managed nodes automatically .
ansible webservers -m setup # View all facts
- hosts: webservers tasks: - name: Print facts debug: msg: | OS: {{ ansible_os_family }} Distribution: {{ ansible_distribution }} IP: {{ ansible_default_ipv4.address }}
Part 7: Conditionals and Loops
Conditionals (when)
- hosts: webservers tasks: - name: Install Apache on Debian apt: name: apache2 state: present when: ansible_os_family == "Debian" - name: Install httpd on RedHat yum: name: httpd state: present when: ansible_os_family == "RedHat" - name: Start service service: name: "{{ 'apache2' if ansible_os_family == 'Debian' else 'httpd' }}" state: started
Loops
- hosts: webservers tasks: - name: Install multiple packages apt: name: "{{ item }}" state: present loop: - git - curl - vim - name: Create multiple users user: name: "{{ item.name }}" groups: "{{ item.groups }}" loop: - { name: 'alice', groups: 'developers' } - { name: 'bob', groups: 'developers' }
Part 8: Templates (Jinja2)
Jinja2 templates allow dynamic configuration files .
Template File (nginx.conf.j2)
server {
listen {{ nginx_port }};
server_name {{ server_name }};
location / {
proxy_pass http://{{ app_host }}:{{ app_port }};
proxy_set_header Host $host;
}
}Playbook Using Template
- hosts: webservers vars: nginx_port: 80 server_name: "{{ inventory_hostname }}" app_host: "{{ groups['appservers'][0] }}" app_port: 8080 tasks: - name: Generate nginx config template: src: nginx.conf.j2 dest: /etc/nginx/conf.d/app.conf notify: restart nginx
Part 9: Roles
Roles are reusable components that organize tasks, variables, handlers, and templates .
Role Directory Structure
roles/nginx/
├── defaults/ # Default variables (lowest precedence)
│ └── main.yml
├── vars/ # Override variables
│ └── main.yml
├── tasks/ # Main task list
│ └── main.yml
├── handlers/ # Change handlers
│ └── main.yml
├── templates/ # Jinja2 templates
│ └── nginx.conf.j2
├── files/ # Static files
│ └── index.html
├── meta/ # Role metadata (dependencies)
│ └── main.yml
└── tests/ # Role tests
└── test.ymlRole Example
# roles/nginx/tasks/main.yml --- - name: Install Nginx apt: name: nginx state: present when: ansible_os_family == "Debian" - name: Copy config template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: restart nginx - name: Start service service: name: nginx state: started enabled: yes
Using a Role in a Playbook
--- - hosts: webservers become: yes roles: - nginx - common - webapp
Role Dependencies
# roles/nginx/meta/main.yml --- dependencies: - role: common - role: firewall firewall_ports: - 80 - 443
Part 10: Ansible Vault (Secrets)
Ansible Vault encrypts sensitive data .
Encrypting Files
# Encrypt a file ansible-vault encrypt secrets.yml # View encrypted file ansible-vault view secrets.yml # Edit encrypted file ansible-vault edit secrets.yml # Decrypt a file ansible-vault decrypt secrets.yml
Using Encrypted Variables
# group_vars/all/vault.yml --- db_password: !vault | $ANSIBLE_VAULT;1.1;AES256 663864396532363436626538...
Running Playbooks with Vault
# Provide password prompt ansible-playbook site.yml --ask-vault-pass # Use vault password file ansible-playbook site.yml --vault-password-file .vault_pass
Part 11: Error Handling and Debugging
Handling Errors
- hosts: webservers tasks: - name: Attempt risky operation command: /usr/local/bin/risky-script register: result ignore_errors: yes - name: Debug output debug: var: result - name: Fail if error fail: msg: "Risky operation failed!" when: result.failed - name: Force failure condition command: /bin/true register: command_result failed_when: "'FAILED' in command_result.stdout" - name: Retry on failure command: /usr/local/bin/unstable-script register: retry_result until: retry_result.rc == 0 retries: 5 delay: 10
Debugging Commands
# Verbose output ansible-playbook site.yml -vvvv # Check syntax ansible-playbook site.yml --syntax-check # List tasks ansible-playbook site.yml --list-tasks # List hosts ansible-playbook site.yml --list-hosts # Start at a specific task ansible-playbook site.yml --start-at-task "Install Nginx"
Part 12: Advanced Topics
Ansible Collections
Collections are the modern way to organize and distribute Ansible content .
# Install a collection ansible-galaxy collection install community.docker # Use a collection module - name: Manage Docker container community.docker.docker_container: name: webapp image: nginx:latest state: started
Dynamic Inventory Plugins
# aws_ec2.yml plugin: amazon.aws.aws_ec2 regions: - us-west-2 keyed_groups: - key: tags.Environment prefix: env
Ansible Tower / AWX
Ansible Tower is a web-based management solution for Ansible that provides:
Web UI for playbook management
Role-based access control
Scheduling and notifications
REST API for integration
Ansible Commands Cheat Sheet
# Inventory and Ping ansible all -m ping ansible webservers -i hosts.ini -m ping # Ad-Hoc Commands ansible webservers -m apt -a "name=nginx state=present" --become ansible webservers -m service -a "name=nginx state=started" ansible webservers -m copy -a "src=file.txt dest=/tmp/file.txt" # Playbooks ansible-playbook site.yml ansible-playbook site.yml -i hosts.ini ansible-playbook site.yml --check # Dry run ansible-playbook site.yml --diff # Show file changes ansible-playbook site.yml -vvvv # Verbose debug output # Roles and Collections ansible-galaxy role init role-name ansible-galaxy collection install community.general # Vault ansible-vault encrypt secrets.yml ansible-vault view secrets.yml ansible-vault edit secrets.yml
Best Practices Summary
Summary
Ansible is a powerful, agentless automation tool that uses simple YAML playbooks to manage infrastructure.
Comments
Post a Comment