Ansible inventory defines which hosts to manage. Roles provide a standardized directory structure for reusable automation. The Ansible Galaxy community provides 30,000+ pre-built roles.
| Item | Syntax / Value | Description |
|---|---|---|
| Inventory | File listing managed hosts and groups | INI or YAML format: [webservers] host1 host2 |
| INI inventory | [group] host1 ansible_host=1.2.3.4 | Simple INI format — most common |
| YAML inventory | all: hosts: host1: ansible_host: 1.2.3.4 | YAML inventory — more flexible |
| Dynamic inventory | Script that outputs JSON — for cloud providers | AWS EC2, Azure, GCP plugins generate inventory |
| ansible_host | Connection hostname/IP (if different from inventory name) | host1 ansible_host=192.168.1.10 |
| ansible_user | SSH username to connect as | ansible_user: ubuntu |
| ansible_port | SSH port (default 22) | ansible_port: 2222 |
| ansible_ssh_private_key_file | Path to SSH private key | ansible_ssh_private_key_file: ~/.ssh/id_rsa |
| ansible_python_interpreter | Python path on remote host | ansible_python_interpreter: /usr/bin/python3 |
| [group:children] | Group of groups | [production:children] webservers databases |
| [group:vars] | Variables for group in inventory | [webservers:vars] app_port=80 |
| Role | Reusable unit of automation with standard structure | ansible-galaxy init myrole |
| tasks/main.yml | Role task entry point | Main task file for the role |
| handlers/main.yml | Role handler definitions | Handlers triggered by tasks in this role |
| templates/ | Jinja2 templates for config files | vhost.conf.j2, nginx.conf.j2 |
| files/ | Static files to copy to hosts | SSL certs, scripts, config files |
| vars/main.yml | Role variable definitions | Default variables for the role |
| defaults/main.yml | Role default variables (lowest priority) | Can be overridden by any other var source |
| meta/main.yml | Role metadata and dependencies | galaxy_info, dependencies list |
| ansible.cfg | Ansible configuration file | inventory, remote_user, private_key_file settings |
| ansible-galaxy | CLI for role management | ansible-galaxy install geerlingguy.apache |
| ansible-galaxy init | Create new role skeleton | ansible-galaxy init my_custom_role |
| requirements.yml | List of roles to install | ansible-galaxy install -r requirements.yml |
| Ansible Vault | Encrypt sensitive variables | ansible-vault encrypt vars/secrets.yml |
# Inventory and Role Structure
# ── inventory/production ──────────────────────────────────────
[webservers]
web01 ansible_host=10.0.1.10
web02 ansible_host=10.0.1.11
[databases]
db01 ansible_host=10.0.2.10 ansible_port=22
[loadbalancers]
lb01 ansible_host=10.0.0.5
[production:children]
webservers
databases
loadbalancers
[production:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/production.pem
ansible_python_interpreter=/usr/bin/python3
# ── group_vars/webservers.yml ─────────────────────────────────
app_dir: /var/www/React/prod
app_user: www-data
enable_https: true
cert_email: ops@mywebuniversity.com
# ── roles/webserver/tasks/main.yml ───────────────────────────
---
- name: Install web packages
ansible.builtin.apt:
name: "{{ webserver_packages }}"
state: present
update_cache: true
- name: Configure Apache
ansible.builtin.template:
src: vhost.conf.j2
dest: /etc/apache2/sites-available/mywebuniversity.conf
notify: Restart Apache
- name: Deploy application
ansible.builtin.include_tasks: deploy.yml
when: deploy_app | default(true)
# ── roles/webserver/defaults/main.yml ────────────────────────
---
webserver_packages:
- apache2
- python3
- python3-pip
app_port: 80
app_dir: /var/www/html
enable_https: false
# ── roles/webserver/handlers/main.yml ────────────────────────
---
- name: Restart Apache
ansible.builtin.service:
name: apache2
state: restarted
- name: Reload Apache
ansible.builtin.service:
name: apache2
state: reloaded
# ── roles/webserver/templates/vhost.conf.j2 ──────────────────
<VirtualHost *:{{ app_port }}>
ServerName {{ server_name | default(ansible_fqdn) }}
DocumentRoot {{ app_dir }}
<Directory {{ app_dir }}>
Options +ExecCGI -Indexes
AllowOverride All
Require all granted
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory /usr/lib/cgi-bin/>
Options +ExecCGI
AddHandler cgi-script .cgi .py
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/{{ app_name }}_error.log
CustomLog ${APACHE_LOG_DIR}/{{ app_name }}_access.log combined
</VirtualHost>
# ── requirements.yml ─────────────────────────────────────────
---
roles:
- name: geerlingguy.apache
version: "3.2.0"
- name: geerlingguy.certbot
version: "5.1.0"
- src: https://github.com/example/custom-role
# Install: ansible-galaxy install -r requirements.yml
# ── Vault: encrypt secrets ────────────────────────────────────
# Create encrypted file:
# ansible-vault create vars/secrets.yml
# ansible-vault encrypt vars/secrets.yml
# Edit encrypted file:
# ansible-vault edit vars/secrets.yml
# Run playbook with vault:
# ansible-playbook site.yml --ask-vault-pass
# ansible-playbook site.yml --vault-password-file ~/.vault_pass
# ── ansible.cfg ──────────────────────────────────────────────
[defaults]
inventory = inventory/production
remote_user = ubuntu
private_key_file = ~/.ssh/production.pem
host_key_checking = False
retry_files_enabled = False
stdout_callback = yaml
callback_whitelist = timer, profile_tasks
[privilege_escalation]
become = True
become_method = sudo
become_user = root