Ansible: architecture and practical techniques
๐๏ธ Ansible architecture
What I like in Ansible is simplicity and agentless architecture:
- agentless model - uses existing SSH (Linux/Unix) or WinRM (Windows) protocols to communicate with managed hosts
- modular structure - everything is based on declarative YAML files: playbooks, roles and inventory
- idempotency - operations can be safely repeated without risk of duplicate changes
Role-based project organization
Example of role based structure:
ansible-project/
โโโ ๐ inventory/
โ โโโ development.yml # Dev environment definition
โ โโโ production.yml # Production environment definition
โโโ ๐ group_vars/
โ โโโ all.yml # Variables common to all groups
โ โโโ webservers.yml # Variables for webservers group
โ โโโ dbservers.yml # Variables for dbservers group
โโโ ๐ host_vars/
โ โโโ specific-host.yml # Variables for specific host
โโโ ๐ roles/
โ โโโ ๐ common/ # Common role for all servers
โ โ โโโ ๐ tasks/
โ โ โ โโโ main.yml # Main role tasks
โ โ โโโ ๐ handlers/
โ โ โ โโโ main.yml # Handlers
โ โ โโโ ๐ templates/
โ โ โ โโโ ntp.conf.j2 # Configuration file templates
โ โ โโโ ๐ files/
โ โ โ โโโ banner.txt # Static files
โ โ โโโ ๐ vars/
โ โ โ โโโ main.yml # Internal role variables
โ โ โโโ ๐ defaults/
โ โ โโโ main.yml # Default variable values
โ โโโ ๐ webserver/ # Role for web servers
โ โโโ ๐ database/ # Role for database servers
โโโ site.yml # Main playbook
โโโ webservers.yml # Playbook for web servers
โโโ dbservers.yml # Playbook for database servers
Practical techniques
Task delegation
Task delegation allows executing specific operations on a different host than the currently processed one:
- name: Register new server in load balancer
shell: /usr/local/bin/register_node.sh {{ inventory_hostname }}
delegate_to: load_balancer8
# This task will execute on the load_balancer8 host
Collections instead of simple playbooks
Don't reinvent the wheel - use ready-made collections from Ansible Galaxy:
ansible-galaxy collection install community.docker
# Usage in playbook
- name: Run PostgreSQL container
community.docker.docker_container:
name: db
image: postgres:13
ports:
- "5432:5432"
๐ Ansible Vault for sensitive data
# Encrypting password files
ansible-vault encrypt group_vars/all/vault.yml
# Running playbooks with encrypted data
ansible-playbook site.yml --ask-vault-pass
โก Performance optimization
- hosts: all
gather_facts: no # disable fact gathering when unnecessary
# or
gather_subset: network # gather only selected facts
๐ต๏ธ Diff mode
Combining --diff
with --check
allows seeing what changes will be made without actually making them.
๐ Execution strategies
- hosts: webservers
strategy: free # parallel task execution without synchronization
# alternatives: linear (default), debug (interactive)
tasks:
# tasks...
๐ Error handling and loops
- name: Start services
service:
name: "{{ item }}"
state: started
loop:
- nginx
- redis
- postgresql
ignore_errors: yes # continue despite errors
register: service_result
- name: Notify about errors
mail:
to: "admin@foobar.com"
subject: "Service startup error"
body: "There was a problem starting services"
when: service_result.failed
๐ Advanced role techniques
๐ role dependencies
# roles/webserver/meta/main.yml
dependencies:
- role: common
- role: security
vars:
security_level: high
๐งฉ Reusable roles with parameters
# playbook.yml
- hosts: webservers
roles:
- role: nginx
vars:
nginx_port: 80
ssl_enabled: true
- role: nginx
vars:
nginx_port: 8080
server_name: "api.foobar.com"
๐ Dynamic inventory
Instead of static host lists, use dynamic inventory for cloud infrastructure:
# AWS EC2
ansible-playbook -i inventory_aws_ec2.yml site.yml
# Azure
ansible-playbook -i inventory_azure_rm.yml site.yml
๐ฆ Control flow - conditional handling
- name: Install distribution-specific packages
include_tasks: "{{ ansible_os_family | lower }}.yml"
# automatically loads debian.yml or redhat.yml depending on system
๐ Monitoring and debugging
๐ Variable debugging
- name: Display host information
debug:
var: ansible_facts
verbosity: 1 # displays only with -v or higher level
๐ Callback plugins
This will enable displaying execution time for individual tasks.
๐ Best practices
- ๐ฆ maintain small, specialized roles - each role in general should have one specific purpose
- ๐ test roles in isolation - use
molecule
for role testing - ๐ document variables - use comments in
defaults/main.yml
files - ๐ never store credentials in plain text - always use ansible vault or other vault derivative
- ๐ง use tags for selective execution -
ansible-playbook site.yml --tags "configuration,packages"
- ๐งช check changes before deployment - use
--check
and--diff
๐ Summary
Ansible enables infrastructure automation without excessive complexity. Role-based approach provides modularity, code reuse, and easier management. With task delegation, collections, and execution strategies, you can create flexible and efficient automation solutions.
๐ Useful resources:
- Ansible Galaxy - roles and collections repository
- Ansible Docs - official documentation
- Molecule - role testing tool