LearnThatStack Ace your next interview
DevOps · Free

Ansible.
Interview cheat sheet.

Quick reference for Ansible - sectioned for fast scanning. Skim the part you're shaky on, walk in confident.

DevOps 23-section reference ~6 min read

Summary

Ansible is an agentless, push-based configuration management and automation tool that uses SSH for communication and YAML for playbooks. It excels in infrastructure provisioning, configuration management, application deployment, and orchestration. Key strengths include idempotent operations, human-readable YAML syntax, extensive module library, and no agent requirements. Essential for DevOps professionals working on infrastructure automation, CI/CD pipelines, and multi-environment deployments where consistency and reliability are critical.

1. Core Concepts

What is Ansible?

  • Agentless automation tool (uses SSH/WinRM)
  • Push-based configuration management
  • Written in Python, uses YAML for playbooks
  • Idempotent - running multiple times produces same result

Key Components

  • Control Node: Machine where Ansible is installed
  • Managed Nodes: Target machines being configured
  • Inventory: List of managed nodes
  • Modules: Units of code Ansible executes
  • Tasks: Units of action in Ansible
  • Playbooks: YAML files containing plays
  • Roles: Reusable collection of tasks, vars, handlers

2. Installation & Setup

# Install Ansible
pip install ansible
# or
sudo apt-get install ansible

# Test connection
ansible all -m ping -i inventory.ini

# Ad-hoc command syntax
ansible [pattern] -m [module] -a "[arguments]" -i [inventory]

3. Inventory

Static Inventory (inventory.ini)

[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.example.com ansible_host=192.168.1.100

[all:vars]
ansible_user=admin
ansible_ssh_private_key_file=/path/to/key

Dynamic Inventory

# Can use scripts that return JSON
# AWS EC2, Azure, GCP plugins available
plugin: amazon.aws.ec2
regions:
  - us-east-1

4. Playbook Structure

Basic Playbook

---
- name: Configure webservers
  hosts: webservers
  become: yes
  vars:
    http_port: 80
  
  tasks:
    - name: Install Apache
      apt:
        name: apache2
        state: present
      when: ansible_os_family == "Debian"
    
    - name: Start Apache
      service:
        name: apache2
        state: started
        enabled: yes

5. Variables

Variable Precedence (Low to High)

  1. Role defaults
  2. Inventory vars
  3. Playbook vars
  4. Host facts
  5. Play vars
  6. Task vars
  7. Extra vars (-e)

Variable Definition

# In playbook
vars:
  app_name: myapp
  
# In group_vars/all.yml
db_port: 5432

# Using variables
- debug:
    msg: "App {{ app_name }} uses port {{ db_port }}"

6. Facts & Magic Variables

# Gathering facts
- name: Display facts
  debug:
    var: ansible_facts

# Common facts
ansible_hostname
ansible_os_family
ansible_distribution
ansible_memtotal_mb

# Magic variables
hostvars['hostname']
group_names
groups['webservers']
inventory_hostname

7. Conditionals & Loops

Conditionals

- name: Install on RedHat
  yum:
    name: httpd
  when: ansible_os_family == "RedHat"

- name: Multiple conditions
  service:
    name: nginx
  when:
    - ansible_os_family == "Debian"
    - ansible_distribution_major_version == "20"

Loops

# Simple loop
- name: Install packages
  apt:
    name: "{{ item }}"
  loop:
    - nginx
    - mysql
    - php

# Loop with dict
- name: Create users
  user:
    name: "{{ item.key }}"
    groups: "{{ item.value }}"
  loop: "{{ users | dict2items }}"

8. 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

9. Templates (Jinja2)

# template.j2
server {
    listen {{ http_port }};
    server_name {{ ansible_hostname }};
    
    {% for site in sites %}
    location /{{ site.name }} {
        proxy_pass {{ site.backend }};
    }
    {% endfor %}
}

10. Roles

Role Structure

roles/
  webserver/
    tasks/main.yml
    handlers/main.yml
    templates/
    files/
    vars/main.yml
    defaults/main.yml
    meta/main.yml

Using Roles

- hosts: webservers
  roles:
    - common
    - webserver
    - role: database
      vars:
        db_name: production

11. Error Handling

# Ignore errors
- name: This might fail
  command: /bin/false
  ignore_errors: yes

# Block error handling
- block:
    - name: Try this
      command: /bin/something
  rescue:
    - name: Do this on error
      debug:
        msg: "Task failed"
  always:
    - name: Always do this
      debug:
        msg: "Cleanup"

# Failed when
- command: /usr/bin/somecommand
  register: result
  failed_when: "'ERROR' in result.stderr"

12. Vault (Encryption)

# Create encrypted file
ansible-vault create secrets.yml

# Encrypt existing file
ansible-vault encrypt vars.yml

# Edit encrypted file
ansible-vault edit secrets.yml

# Run playbook with vault
ansible-playbook site.yml --ask-vault-pass

13. Common Modules

File Operations

# File module
- file:
    path: /etc/app
    state: directory
    mode: '0755'

# Copy module
- copy:
    src: app.conf
    dest: /etc/app/
    backup: yes

# Template module
- template:
    src: config.j2
    dest: /etc/app/config

Package Management

# Package module (generic)
- package:
    name: nginx
    state: present

# APT (Debian/Ubuntu)
- apt:
    name: apache2
    update_cache: yes

# YUM (RedHat/CentOS)
- yum:
    name: httpd
    state: latest

Service Management

- service:
    name: nginx
    state: started
    enabled: yes

# Systemd specific
- systemd:
    name: nginx
    state: restarted
    daemon_reload: yes

14. Advanced Topics

Custom Modules

#!/usr/bin/python
from ansible.module_utils.basic import AnsibleModule

def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(type='str', required=True),
            state=dict(type='str', default='present')
        )
    )
    
    result = dict(
        changed=False,
        message=''
    )
    
    module.exit_json(**result)

if __name__ == '__main__':
    main()

Strategies

# Execution strategies
- hosts: all
  strategy: free  # Don't wait for all hosts
  # Other options: linear (default), debug

Delegation

- name: Take out of load balancer
  command: /usr/bin/remove_from_lb {{ inventory_hostname }}
  delegate_to: loadbalancer
  
- name: Run locally
  command: /usr/bin/local_script
  delegate_to: localhost

15. Best Practices

  1. Use version control for playbooks
  2. Keep it simple - one role, one purpose
  3. Use meaningful names for tasks
  4. Always use state parameter
  5. Tag your tasks for selective execution
  6. Use handlers for service restarts
  7. Encrypt sensitive data with Vault
  8. Test with --check (dry run)
  9. Use ansible-lint for code quality
  10. Document your playbooks

16. Performance Optimization

# Fact caching
[defaults]
fact_caching = jsonfile
fact_caching_connection = /tmp/facts_cache

# Pipelining
[ssh_connection]
pipelining = True

# Forks (parallel execution)
[defaults]
forks = 50

# Disable fact gathering when not needed
- hosts: all
  gather_facts: no

17. Debugging

# Debug module
- debug:
    msg: "Variable value: {{ my_var }}"
    verbosity: 2

# Register and debug
- command: /usr/bin/something
  register: output
- debug:
    var: output

# Pause for debugging
- pause:
    prompt: "Check the system and press enter"

18. Ansible vs Other Tools Comparison

Feature Ansible Puppet Chef Salt
Agent Agentless (SSH) Agent-based Agent-based Agent-based
Language YAML Ruby DSL Ruby DSL YAML/Python
Model Push Pull Pull Push/Pull
Learning Curve Easy Moderate Steep Moderate
Architecture Simple Master-Agent Server-Node Master-Minion

19. Key Concepts Deep Dive

Idempotency Patterns

  • File Operations: state: present/absent/directory/link
  • Package Management: state: present/latest/absent
  • Service Management: state: started/stopped/restarted
  • Configuration: Use templates with checksums

Variable Precedence (Highest to Lowest)

  1. Extra vars (-e command line)
  2. Task vars (in task definition)
  3. Block vars (in block definition)
  4. Role and include vars
  5. Play vars_prompt
  6. Play vars_files
  7. Play vars
  8. Set_facts / registered vars
  9. Host facts
  10. Playbook host_vars
  11. Playbook group_vars
  12. Inventory host_vars
  13. Inventory group_vars
  14. Inventory vars
  15. Role defaults

Include vs Import Differences

  • Static (import_*): Processed at parse time, can't use loops/conditionals on import
  • Dynamic (include_*): Processed at runtime, supports loops/conditionals

Multi-OS Handling Strategies

# Method 1: OS Family conditionals
- name: Install Apache (Debian)
  apt: name=apache2
  when: ansible_os_family == "Debian"

- name: Install Apache (RedHat)
  yum: name=httpd
  when: ansible_os_family == "RedHat"

# Method 2: Variable mapping
vars:
  apache_package:
    Debian: apache2
    RedHat: httpd
    
- name: Install Apache
  package:
    name: "{{ apache_package[ansible_os_family] }}"

20. Ansible Tower/AWX Features

Enterprise Features

  • Role-Based Access Control (RBAC)
  • Job Templates & Workflows
  • Credential Management
  • Inventory Sync from Cloud Providers
  • RESTful API
  • Audit Trails & Logging
  • Schedule Jobs
  • Survey Forms for Job Customization

Tower vs AWX

  • Tower: Red Hat commercial product with support
  • AWX: Open-source upstream project
  • Key Differences: Support, stability, additional enterprise features

21. Troubleshooting Commands

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

# List hosts
ansible all --list-hosts -i inventory

# Dry run
ansible-playbook playbook.yml --check

# Step through tasks
ansible-playbook playbook.yml --step

# Start at specific task
ansible-playbook playbook.yml --start-at-task="Install Apache"

# Run specific tags
ansible-playbook playbook.yml --tags="configuration"

# Increase verbosity
ansible-playbook playbook.yml -vvv

22. Security Best Practices

  1. Use SSH keys instead of passwords
  2. Encrypt sensitive data with ansible-vault
  3. Use become instead of running as root
  4. Limit sudo permissions for ansible user
  5. Validate input in custom modules
  6. Use no_log: true for sensitive tasks
  7. Rotate vault passwords regularly

Remember: Ansible's power lies in its simplicity. Start simple, grow complex only when needed.

Found this useful? Pass it on.
Pro · $10/mo

The sheet is free. Pro goes deeper.

Pro opens the full question library behind every sheet, every refresher and a monthly AI allowance. One subscription, all formats.

Full question library All refreshers Cancel anytime