π 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