Ansible Guide: Agentless Configuration Management
Ansible automates server configuration, application deployment, and orchestration without installing agents on managed hosts. It connects over SSH, executes tasks declaratively, and is idempotent by design.
Inventory
The inventory lists the hosts Ansible manages. It can be INI or YAML format.
INI format (/etc/ansible/hosts or a custom file):
[webservers]
web1.example.com
web2.example.com ansible_port=2222
[dbservers]
db1.example.com ansible_user=admin
[production:children]
webservers
dbservers
[all:vars]
ansible_python_interpreter=/usr/bin/python3
YAML format (inventory.yml):
all:
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
ansible_port: 2222
dbservers:
hosts:
db1.example.com:
ansible_user: admin
vars:
ansible_python_interpreter: /usr/bin/python3
Playbook Structure
A playbook is a YAML file describing a set of plays. Each play targets a group of hosts and runs tasks in order:
---
- name: Configure web servers
hosts: webservers
become: true
vars:
http_port: 80
doc_root: /var/www/html
tasks:
- name: Install nginx
apt:
name: nginx
state: present
update_cache: true
- name: Deploy site config
template:
src: templates/nginx-site.conf.j2
dest: /etc/nginx/sites-available/default
notify: Reload nginx
- name: Ensure nginx is running
service:
name: nginx
state: started
enabled: true
handlers:
- name: Reload nginx
service:
name: nginx
state: reloaded
Handlers run only once at the end of a play, even if notified multiple times.
Common Modules
Ansible ships with hundreds of modules. The most-used ones for sysadmins:
| Module | Purpose | Example |
|---|---|---|
apt / yum |
Package management | apt: name=nginx state=latest |
copy |
Copy files to remote hosts | copy: src=app.conf dest=/etc/app/ |
template |
Render Jinja2 templates | template: src=conf.j2 dest=/etc/app.conf |
service |
Manage system services | service: name=nginx state=restarted |
file |
Manage files and directories | file: path=/data state=directory mode=0755 |
command / shell |
Run arbitrary commands | command: /opt/app/migrate.sh |
user |
Manage user accounts | user: name=deploy shell=/bin/bash |
Roles
Roles organize playbooks into reusable components with a standard directory structure:
roles/
nginx/
defaults/
main.yml # default variables (lowest precedence)
tasks/
main.yml # task list
templates/
nginx.conf.j2 # Jinja2 templates
handlers/
main.yml # handlers
files/ # static files
meta/
main.yml # role metadata and dependencies
Use a role in a playbook:
- hosts: webservers
become: true
roles:
- nginx
- { role: certbot, when: ssl_enabled }
Install community roles from Ansible Galaxy:
ansible-galaxy install geerlingguy.docker
Ansible Vault
Encrypt sensitive variables (passwords, API keys) so they can be committed to version control safely:
# Encrypt a file
ansible-vault encrypt vars/secrets.yml
# Edit an encrypted file
ansible-vault edit vars/secrets.yml
# Run a playbook that uses encrypted vars
ansible-playbook site.yml --ask-vault-pass
# Use a vault password file for automation
ansible-playbook site.yml --vault-password-file ~/.vault_pass
Encrypt a single variable inline:
ansible-vault encrypt_string 'SuperSecret123' --name 'db_password'
Ad-Hoc Commands
For quick one-off tasks without writing a playbook:
# Ping all hosts
ansible all -m ping
# Check disk space on web servers
ansible webservers -a "df -h"
# Restart a service
ansible dbservers -m service -a "name=postgresql state=restarted" --become
# Copy a file
ansible all -m copy -a "src=motd.txt dest=/etc/motd" --become
Ad-hoc commands are ideal for troubleshooting and one-time operations.
Return to the DevOps hub or continue to Terraform Guide and Git for Sysadmins.