Ansible is an open source automation tool for configuration management, application deployment and agentless orchestration.
Installation
| Platform | Command |
|---|
| Ubuntu/Debian | sudo apt update && sudo apt install ansible |
| CentOS/RHEL | sudo yum install ansible |
| Python pip | pip3 install ansible |
| macOS (Homebrew) | brew install ansible |
Recommended project structure
ansible-project/
├── inventory/ # Inventories
│ ├── production/
│ │ ├── hosts.ini
│ │ └── group_vars/
│ └── staging/
│ └── hosts.ini
├── roles/ # Reusable roles
│ ├── common/
│ ├── nginx/
│ └── mysql/
├── playbooks/ # Main playbooks
│ ├── site.yml
│ └── webservers.yml
├── group_vars/ # Variables per group
├── host_vars/ # Variables per host
└── ansible.cfg # Configuration
ansible.cfg file
[defaults]
inventory = inventory/ # Default inventory folder
remote_user = ansible # Default SSH user
host_key_checking = False # No SSH key verification (dev)
retry_files_enabled = False # No .retry files
gathering = smart # Smart facts gathering
fact_caching = memory # Cache facts in memory
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s # Persistent SSH connections
pipelining = True # SSH optimization
Inventory management
| Action | Command |
|---|
| Create inventory | echo "[servers]" > inventory/hosts.ini |
| Global ping test | ansible all -m ping |
| Group ping test | ansible webservers -m ping |
| Ad-hoc command | ansible all -a "uptime" |
| System info | ansible all -m setup |
| Other inventory | ansible all -i staging/hosts.ini -m ping |
Inventory file example
[webservers]
web1 ansible_host=192.168.1.50 ansible_user=admin
web2 ansible_host=192.168.1.51 ansible_user=admin
[databases]
db1 ansible_host=192.168.1.20 ansible_user=root
[all:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_ssh_private_key_file=~/.ssh/id_rsa
Useful inventory variables
# SSH connection
ansible_host=192.168.1.50 # Server IP
ansible_user=admin # SSH user
ansible_port=2222 # SSH port (default: 22)
ansible_ssh_private_key_file=~/.ssh/key # Private key
# Python
ansible_python_interpreter=/usr/bin/python3
# Sudo
ansible_become=yes # Use sudo
ansible_become_user=root # Sudo user
Playbook execution
| Action | Command |
|---|
| Run playbook | ansible-playbook playbook.yml |
| Test mode (dry-run) | ansible-playbook playbook.yml --check |
| Verbose mode | ansible-playbook playbook.yml -vvv |
| Limit to hosts | ansible-playbook playbook.yml --limit webservers |
| List tasks | ansible-playbook playbook.yml --list-tasks |
| Direct host | ansible-playbook -i "192.168.1.50," playbook.yml |
Basic playbook structure
---
- name: Web servers configuration
hosts: webservers
become: yes
vars:
nginx_port: 80
tasks:
- name: Install nginx
apt:
name: nginx
state: present
update_cache: yes
- name: Start nginx
service:
name: nginx
state: started
enabled: yes
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
Role management
Ansible Galaxy is a community hub for shared roles (optional)
| Action | Command |
|---|
| Create role structure | ansible-galaxy init nginx |
| Create manually | mkdir -p roles/nginx/{tasks,handlers,templates,files,vars,defaults} |
| Install community role | ansible-galaxy install geerlingguy.nginx |
| List installed roles | ansible-galaxy list |
| Remove a role | ansible-galaxy remove geerlingguy.nginx |
| Search for roles | ansible-galaxy search nginx |
requirements.yml file
The requirements.yml file allows you to list and automatically install multiple roles or collections with a single command.
# requirements.yml - Dependencies declaration
---
roles:
# From Galaxy (user.role)
- name: geerlingguy.nginx
version: "3.1.4"
- name: geerlingguy.docker
version: "7.0.2"
# From a Git repo
- name: custom-role
src: https://github.com/user/ansible-custom-role.git
version: main
collections:
# Collections from Galaxy
- name: community.general
version: "8.0.0"
- name: ansible.posix
Install from requirements.yml:
| Action | Command |
|---|
| Install roles | ansible-galaxy install -r requirements.yml |
| Install collections | ansible-galaxy collection install -r requirements.yml |
| Force reinstall | ansible-galaxy install -r requirements.yml --force |
Role structure
roles/nginx/
├── tasks/main.yml # Main tasks
├── handlers/main.yml # Triggered actions (restart services)
├── templates/ # Jinja2 files (.j2)
├── files/ # Static files to copy
├── vars/main.yml # Role variables
├── defaults/main.yml # Default variables
└── meta/main.yml # Metadata (dependencies, etc.)
Using roles in a playbook
---
- name: Web servers deployment
hosts: webservers
become: yes
roles:
- common # Basic configuration
- nginx # Nginx installation and config
- firewall # Firewall configuration
# Or with parameters
- name: Config with variables
hosts: webservers
roles:
- role: nginx
vars:
nginx_port: 8080
nginx_user: www-data
Essential modules
Package management
# APT (Ubuntu/Debian)
- name: Install nginx
apt:
name: nginx
state: present
update_cache: yes
# YUM/DNF (CentOS/RHEL/Fedora)
- name: Install httpd
yum:
name: httpd
state: present
# Universal package
- name: Install git
package:
name: git
state: present
File management
# Copy file
- name: Copy configuration
copy:
src: files/nginx.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
backup: yes
# Jinja2 template
- name: Generate dynamic config
template:
src: templates/config.j2
dest: /etc/app/config.conf
# Create folder
- name: Create directory
file:
path: /opt/myapp
state: directory
mode: '0755'
Service management
# Control service
- name: Start and enable nginx
service:
name: nginx
state: started
enabled: yes
# Systemd service
- name: Reload systemd
systemd:
name: myapp
state: reloaded
daemon_reload: yes
Ansible Vault
| Action | Command |
|---|
| Create encrypted file | ansible-vault create secrets.yml |
| Edit file | ansible-vault edit secrets.yml |
| View content | ansible-vault view secrets.yml |
| Change password | ansible-vault rekey secrets.yml |
| Encrypt existing file | ansible-vault encrypt vars.yml |
| Decrypt file | ansible-vault decrypt vars.yml |
| Run with vault | ansible-playbook site.yml --ask-vault-pass |
Best practices
| Practice | Description |
|---|
| Idempotence | Tasks always produce the same result |
| Naming | Clearly name all tasks |
| Testing | Use --check before deployment |
| Roles | Organize into reusable roles |
| Secrets | Encrypt with ansible-vault |
| Tags | Use tags for partial executions |