Skip to content

Ansible Basic Concepts

Core Components

Control Node

  • Machine where Ansible is installed
  • Executes playbooks and commands
  • Must run Linux/Unix
  • Cannot be a Windows host

Managed Nodes (Hosts)

  • Systems managed by Ansible
  • No agent installation required
  • Needs Python installed
  • Can be any OS

Inventory

Static list of managed nodes:

# inventory.ini
[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.example.com
db2.example.com

[all:vars]
ansible_user=deploy

Modules

Modules are units of code that perform specific tasks:

# Example module usage
- name: Ensure Apache is installed
  apt:
    name: apache2
    state: present

- name: Copy file
  copy:
    src: /src/file
    dest: /dest/file

Tasks

Individual units of work:

tasks:
  - name: Install package
    apt:
      name: nginx
      state: present

  - name: Start service
    service:
      name: nginx
      state: started

Playbooks

YAML files containing tasks and configurations:

---
- name: Configure webserver
  hosts: webservers
  become: true

  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present

    - name: Start nginx
      service:
        name: nginx
        state: started
        enabled: true

Key Concepts

Idempotency

Running a playbook multiple times should result in the same outcome:

# Idempotent task
- name: Create directory
  file:
    path: /app/data
    state: directory
    mode: '0755'

# Non-idempotent task (avoid)
- name: Create directory
  command: mkdir /app/data

Facts

System information gathered by Ansible:

- name: Display facts
  debug:
    msg: "OS: {{ ansible_os_family }}, Memory: {{ ansible_memtotal_mb }}MB"

Variables

Store and reuse values:

vars:
  http_port: 80
  max_clients: 200

tasks:
  - name: Configure port
    template:
      src: nginx.conf.j2
      dest: /etc/nginx/nginx.conf

Handlers

Tasks triggered by changes:

tasks:
  - name: Copy configuration
    copy:
      src: nginx.conf
      dest: /etc/nginx/nginx.conf
    notify: Restart nginx

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

Templates

Jinja2 templates for dynamic files:

# nginx.conf.j2
server {
    listen {{ http_port }};
    server_name {{ server_name }};

    location / {
        root {{ web_root }};
    }
}

Command Line Tools

ansible

Run ad-hoc commands:

# Execute command on all hosts
ansible all -i inventory -m command -a "uptime"

# Install package on webservers
ansible webservers -i inventory -m apt -a "name=nginx state=present"

ansible-playbook

Execute playbooks:

# Run playbook
ansible-playbook -i inventory site.yml

# Run with variables
ansible-playbook -i inventory site.yml -e "version=1.2.3"

ansible-vault

Manage encrypted content:

# Create encrypted file
ansible-vault create secrets.yml

# Edit encrypted file
ansible-vault edit secrets.yml

# Encrypt existing file
ansible-vault encrypt vars.yml

Working with Roles

Role Structure

roles/
└── webserver/
    ├── defaults/
    │   └── main.yml
    ├── files/
    ├── handlers/
    │   └── main.yml
    ├── meta/
    │   └── main.yml
    ├── tasks/
    │   └── main.yml
    ├── templates/
    └── vars/
        └── main.yml

Using Roles

---
- hosts: webservers
  roles:
    - common
    - webserver

Tags

Selectively run tasks:

tasks:
  - name: Install packages
    apt:
      name: nginx
      state: present
    tags: packages

  - name: Configure application
    template:
      src: app.conf.j2
      dest: /etc/app/conf
    tags: configuration

Run specific tags:

ansible-playbook site.yml --tags "configuration"

Why This Matters

Understanding the core concepts (inventory, modules, tasks, plays, roles) lets you design predictable, maintainable automation. Clear mental models reduce troubleshooting time and improve team collaboration.

Common Pitfalls

  • Running ad-hoc command/shell instead of idempotent modules (use apt, service, file, etc.).
  • Confusing inventory groups and variables; keep group_vars/host_vars organized.
  • Forgetting privilege escalation where needed (become: true).
  • Using Windows as a control node (use Linux/macOS/WSL2 for control; Windows hosts are supported as managed nodes).

Quick Checklist

  • Inventory groups defined and documented.
  • Use modules over raw commands wherever possible.
  • Handlers used for service restarts upon change.
  • Templates parameterized via variables.
  • Idempotence verified by running playbooks twice.

Next Steps

  • Build your first role and wire it into a play.
  • Add linting (ansible-lint) and pre-commit hooks.
  • Introduce Molecule tests for your roles as they mature.