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/shellinstead of idempotent modules (useapt,service,file, etc.). - Confusing inventory groups and variables; keep
group_vars/host_varsorganized. - 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.