Ansible IaC Automation Configuration

Ansible Playbooks: Configuration Management from Scratch

FO
Farida Osei
Systems Automation Engineer
Jul 25, 2025
22 min read

What You'll Learn

How to automate server configuration with Ansible Playbooks — inventory, tasks, handlers, variables, roles, and a complete Nginx setup example.

Why Ansible?

Ansible is a powerful configuration management and IT automation tool. Unlike Chef or Puppet, it is agentless. It uses standard SSH to connect to your servers, meaning you don't need to install any custom software on the target machines — just Python.

The Inventory File

The inventory tells Ansible which servers to manage. It can be a static INI file or dynamic (pulling from AWS/GCP).

inventory.ini
[webservers]
web1.example.com
web2.example.com

[databases]
db1.example.com
db2.example.com

[production:children]
webservers
databases

[production:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/prod_key.pem

Writing a Playbook

Playbooks are YAML files that describe the desired state of your systems. They contain one or more "Plays", which map groups of hosts to tasks.

setup-webserver.yml — Complete Nginx Playbook
---
- name: Setup Web Servers
  hosts: webservers
  become: yes          # Run commands as sudo/root
  vars:
    app_port: 8080
    domain: "example.com"

  tasks:
    - name: Ensure apt cache is up to date
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Install Nginx
      apt:
        name: nginx
        state: present

    - name: Create app directory
      file:
        path: /var/www/myapp
        state: directory
        owner: www-data
        group: www-data
        mode: '0755'

    - name: Deploy custom index.html template
      template:
        src: templates/index.html.j2
        dest: /var/www/myapp/index.html
      notify: restart nginx   # Triggers handler if file changes!

    - name: Configure Nginx virtual host
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/myapp.conf
      notify: restart nginx

    - name: Enable Nginx site (create symlink)
      file:
        src: /etc/nginx/sites-available/myapp.conf
        dest: /etc/nginx/sites-enabled/myapp.conf
        state: link
      notify: restart nginx

    - name: Ensure Nginx is running and enabled on boot
      service:
        name: nginx
        state: started
        enabled: yes

  # Handlers only run once at the end of the play, 
  # and only if notified by a changed task
  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted

Running Commands

bash
# Ad-hoc command: ping all servers
ansible all -i inventory.ini -m ping

# Ad-hoc command: check disk space
ansible webservers -i inventory.ini -m command -a "df -h"

# Run a playbook
ansible-playbook -i inventory.ini setup-webserver.yml

# Dry run (check mode) - show what would change without doing it
ansible-playbook -i inventory.ini setup-webserver.yml --check

# Syntax check
ansible-playbook setup-webserver.yml --syntax-check

Ansible Roles (For Larger Projects)

As your playbooks grow, you should split them into Roles. A role bundles variables, tasks, files, and templates into a standardized directory structure.

# Create a skeleton role
ansible-galaxy init nginx_role

# Using a role in a playbook:
- name: Setup Web Server
  hosts: webservers
  roles:
    - common_security
    - nginx_role
    - app_deploy

Keep Reading

D
DevOps

Docker Networking Demystified: Bridge, Host & Overlay

8 min read Read More
C
Cloud

AWS IAM Roles vs Users vs Policies

10 min read Read More
P
Programming

Understanding Python's GIL & Multiprocessing

14 min read Read More