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.