skip to content

Search

Syspirit
EN

Ansible

Automation and configuration management with playbooks!

DevOps
Published on
Updated on

Ansible is an open source automation tool for configuration management, application deployment and agentless orchestration.

Installation

PlatformCommand
Ubuntu/Debiansudo apt update && sudo apt install ansible
CentOS/RHELsudo yum install ansible
Python pippip3 install ansible
macOS (Homebrew)brew install ansible

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

ActionCommand
Create inventoryecho "[servers]" > inventory/hosts.ini
Global ping testansible all -m ping
Group ping testansible webservers -m ping
Ad-hoc commandansible all -a "uptime"
System infoansible all -m setup
Other inventoryansible 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

ActionCommand
Run playbookansible-playbook playbook.yml
Test mode (dry-run)ansible-playbook playbook.yml --check
Verbose modeansible-playbook playbook.yml -vvv
Limit to hostsansible-playbook playbook.yml --limit webservers
List tasksansible-playbook playbook.yml --list-tasks
Direct hostansible-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)

ActionCommand
Create role structureansible-galaxy init nginx
Create manuallymkdir -p roles/nginx/{tasks,handlers,templates,files,vars,defaults}
Install community roleansible-galaxy install geerlingguy.nginx
List installed rolesansible-galaxy list
Remove a roleansible-galaxy remove geerlingguy.nginx
Search for rolesansible-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:

ActionCommand
Install rolesansible-galaxy install -r requirements.yml
Install collectionsansible-galaxy collection install -r requirements.yml
Force reinstallansible-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

ActionCommand
Create encrypted fileansible-vault create secrets.yml
Edit fileansible-vault edit secrets.yml
View contentansible-vault view secrets.yml
Change passwordansible-vault rekey secrets.yml
Encrypt existing fileansible-vault encrypt vars.yml
Decrypt fileansible-vault decrypt vars.yml
Run with vaultansible-playbook site.yml --ask-vault-pass

Best practices

PracticeDescription
IdempotenceTasks always produce the same result
NamingClearly name all tasks
TestingUse --check before deployment
RolesOrganize into reusable roles
SecretsEncrypt with ansible-vault
TagsUse tags for partial executions