Ansible
Ansible is an open-source automation tool for configuring servers, deploying applications, and orchestrating multi-step operations. It's agentless: a control node connects to managed machines over SSH (or WinRM for Windows), pushes small modules, runs them, and removes them. You describe the desired state in YAML playbooks, and Ansible's modules make the changes needed to reach it — and do nothing if the system is already correct.
Ansible, maintained by Red Hat, is widely used for Linux and Windows server configuration, network device automation, patching, and application deployment. It complements provisioning tools like Terraform: Terraform creates the servers, networks, and databases; Ansible configures what runs on them.
TL;DR
- Agentless: needs SSH and Python on Linux targets (WinRM/PowerShell on Windows).
- An inventory lists hosts and groups; a playbook maps groups to tasks that call modules.
- Modules are idempotent — running a playbook twice should change nothing the second time.
- Organize with roles and share via collections on Ansible Galaxy.
- Use variables, Jinja2 templates, and handlers for configuration and service restarts.
- Encrypt secrets with Ansible Vault; preview with
--check --diff; test roles with Molecule.
Quick Example
An inventory and playbook that install NGINX, deploy a templated config, and reload only when it changes:
Core Concepts
Inventory
Static inventories (INI or YAML) list hosts and groups with variables. Dynamic inventories query AWS, Azure, GCP, VMware, or a CMDB so the host list stays current automatically. group_vars/ and host_vars/ directories hold variables per group or host.
Playbooks, Plays, Tasks, and Modules
A playbook contains plays; each play targets hosts and runs tasks in order. Each task calls a module — package, copy, template, user, service, lineinfile, uri, cloud modules, and thousands more. Use fully qualified collection names (ansible.builtin.copy) for clarity.
Idempotency
Modules check current state before acting and report changed only when they modify something. This makes playbooks safe to rerun and turns them into drift correction. The command and shell modules aren't idempotent by default; add creates:, removes:, or changed_when: guards.
Variables, Facts, and Templates
Variables come from inventory, playbooks, roles, the command line, and facts Ansible gathers about each host (OS, IPs, memory). Jinja2 templates render configuration files. Variable precedence has many levels; keep it simple by defining defaults in roles and overrides in group_vars.
Handlers
Handlers run once at the end of a play, and only if notified by a changed task — perfect for restarting a service after its configuration changes.
Roles and Collections
A role packages tasks, handlers, templates, files, defaults, and metadata into a reusable unit (roles/nginx/). Collections bundle roles, modules, and plugins for distribution through Ansible Galaxy or private automation hubs.
Execution Environment and Scale
Execution environments are container images with a pinned Ansible version and dependencies for reproducible runs. AWX (open source) and Red Hat Ansible Automation Platform add a web UI, RBAC, scheduling, credentials management, and audit logs.
Best Practices
Keep Playbooks Idempotent
Prefer purpose-built modules over shell. When you must run commands, add guards so reruns don't repeat changes.
Use Roles With Sensible Defaults
Put defaults in defaults/main.yml (lowest precedence) so users can override them easily.
Encrypt Secrets
Use ansible-vault encrypt_string or vault-encrypted files, or pull secrets from an external manager like HashiCorp Vault at runtime. See Secrets Management.
Preview Changes
Run with --check --diff in pull requests or before production runs; limit blast radius with --limit and serial: rolling batches.
Lint and Test
Use ansible-lint in CI and Molecule to test roles against containers or VMs.
Pin Versions
Pin Ansible core, collections, and Python dependencies (or use execution environments) so runs are reproducible.
Common Mistakes
Shell Commands Everywhere
shell: apt-get install -y nginx works once but reports changes every run and ignores idempotency. Use the package module.
Plain-Text Secrets in Git
Passwords in group_vars end up in repository history. Vault them.
Running Against All Hosts at Once
A bad change applied to every server simultaneously causes a full outage. Use serial and health checks.
Snowflake Servers Maintained Forever
Using Ansible to patch long-lived servers in place for years accumulates drift. Consider immutable images for stateless tiers.
Ignoring Variable Precedence
Variables defined in too many places make it unclear which value wins. Keep a small, documented set of locations.
Comparison
FAQ
What is Ansible used for?
Automating server configuration, application deployment, patching, user management, network device configuration, and multi-step operational workflows across many machines.
Why is Ansible called agentless?
It doesn't require installing a daemon on managed hosts. It connects over SSH or WinRM, runs modules temporarily, and cleans up.
Ansible or Terraform?
Use Terraform to provision infrastructure (VMs, networks, databases) and Ansible to configure the software on it. They're often used together.
What is an Ansible role?
A structured, reusable package of tasks, handlers, templates, files, and default variables for configuring one thing, such as NGINX or PostgreSQL.
How do I store secrets in Ansible?
Encrypt them with Ansible Vault or retrieve them at runtime from an external secrets manager through lookup plugins.
Related Topics
- Infrastructure as Code — The broader practice
- Terraform — Provisioning the infrastructure Ansible configures
- Linux — The most common Ansible target
- Windows Server Administration — Automating Windows with WinRM
- Secrets Management — Vault and external secret stores