Skip to main content

Ansible Playbooks

Ansible Playbooks provide a repeatable, reusable, simple configuration management and multimachine deployment system that is well suited to deploying complex applications. If you need to execute a task with Ansible more than once, you can write a playbook and put the playbook under source control. You can then use the playbook to push new configurations or confirm the configuration of remote systems.

Source: docs.ansible.com


My Favorite Structure​

ansible-project/
├── ansible.cfg
├── inventory
│ └── hosts.ini
├── group_vars
│ └── appservers.yml
├── plays
│ └── setup-example.yml
├── retries
└── roles
└── example
├── handlers
│ └── main.yml
├── tasks
│ └── main.yml
└── templates
└── example.conf.j2

Inventory and Group Variables​

inventory/hosts.ini — Defines hosts and groups​

Input:

[appservers]
app01 ansible_host=10.10.10.11 env=prod
app02 ansible_host=10.10.10.12 env=dev

group_vars/appservers.yml — Variables applied to whole group​

Input:

app_name: "backend_service"
listen_port: 8080
log_level: "info"

env_config:
prod:
db_host: "10.1.1.10"
db_port: 5432
dev:
db_host: "10.1.1.20"
db_port: 5432

Roles​

Roles let you automatically load related vars, files, tasks, handlers, and other Ansible artifacts based on a known file structure. After you group your content into roles, you can easily reuse them and share them with other users.

Handlers​

Sometimes you want a task to run only when a change is made on a machine. For example, you may want to restart a service if a task updates the configuration of that service, but not if the configuration is unchanged.

roles/example/handlers/main.yml​

Input:

- name: Restart apache
ansible.builtin.service:
name: httpd
state: restarted

Tasks​

roles/example/tasks/main.yml​

Input:

- name: Render application configuration
template:
src: example.conf.j2
dest: /etc/example/example.conf
mode: "0644"
notify:
- Restart apache

- name: Ensure service directory exists
file:
path: /etc/example
state: directory
mode: "0755"

Template Rendering​

Templates let you build dynamic config files.

roles/example/templates/example.conf.j2​

Input:

[service]
name = {{ app_name }}
port = {{ listen_port }}
log_level = {{ log_level }}

[database]
host = {{ env_config[hostvars[inventory_hostname].env].db_host }}
port = {{ env_config[hostvars[inventory_hostname].env].db_port }}

Playbook Calling the Role​

plays/setup-example.yml​

Input:

- hosts: appservers
become: yes
gather_facts: yes
roles:
- example

Ansible Configuration​

Ansible reads ansible.cfg to define global behavior for inventory, roles, SSH, retries, and module paths.

Understanding ansible.cfg entries​

Input:

[defaults]
host_key_checking = False
roles_path = roles
library = library
retry_files_save_path=retries

Explanation​

KeyMeaningTechnical Explanation
host_key_checking = FalseDisables SSH host key verificationPrevents Ansible from asking confirmation on unknown host fingerprints during SSH connection.
roles_path = rolesSets the default directory for rolesAnsible will search for roles inside the roles/ folder relative to the project.
library = libraryCustom module directoryAnsible loads any custom modules stored in the library/ path.
retry_files_save_path = retriesWhere to store retry filesIf a play fails, retry files are stored under retries/ for rerunning failed hosts.

Running the Playbook​

introduction about the command before input​

Apply configuration to all appservers.

Input:

ansible-playbook -i inventory/hosts.ini playbook.yml

Output:

TASK [example : Render application configuration] ********************************
changed: [app01]
changed: [app02]

TASK [example : Ensure service directory exists] *********************************
ok: [app01]
ok: [app02]

This shows that the template was rendered and copied, and directory state validated.


Resulting Configuration​

HostenvDB HostPort
app01prod10.1.1.105432
app02dev10.1.1.205432

The config file is built from shared variables but changes per host environment.


Get The Template​

Input:

bash <(curl -s https://pndhkm.github.io/scripts/ansible_playbooks_template.sh)

Output:

Usage: ./ansible_playbooks_template [OPTIONS] <project_folder>

Creates a fully structured Ansible project scaffold.

Examples:
./ansible_playbooks_template my-ansible-project
./ansible_playbooks_template --force infra-setup

Options:
-f, --force Overwrite existing folder if it exists
-h, --help Show this help message