Ansible Project Structure

Standard Ansible project layout with 21 explained components: inventory (production/staging), group_vars (all.yml/webservers.yml), host_vars (server1.yml), roles (common/webserver/database), playbooks (site.yml/web.yml/db.yml), templates (Jinja2), files (static assets), ansible.cfg, requirements.yml.

Overview

Ansible project layout

A well-structured Ansible project is self-documenting, easy to test, and scales to hundreds of hosts without becoming unmanageable. The standard layout separates concerns: inventory (where), variables (what values), roles (how) and playbooks (when and for whom).

Inventory: where

The project root, ansible-project/, is usually a Git repository. inventory/ defines target hosts and groups them logically.

  • inventory/production — The production hosts file (INI or YAML); lists hostnames/IPs and group memberships
  • inventory/staging — Staging/test hosts; same structure, different IPs

Variables: what values

  • group_vars/all.yml — Every host in every group — ansible_user, common package lists, org-wide settings
  • group_vars/webservers.yml — Hosts in the [webservers] group — http_port, nginx_version, ssl settings
  • host_vars/server1.yml — server1 only — Unique IP, custom listen port, host-specific cert paths

Roles and playbooks: how, when and for whom

  • roles/common/ — Baseline on every host: OS updates, users, SSH hardening, monitoring agents
  • roles/webserver/ — Nginx/Apache install, configuration templates, service management
  • roles/database/ — MySQL/PostgreSQL install, DB/user creation, backup config
  • playbooks/site.yml — Master playbook; imports web.yml and db.yml and applies the full stack
  • playbooks/web.yml — Runs webserver and common roles against [webservers]
  • playbooks/db.yml — Runs database and common roles against [databases]

Supporting files

  • templates/ — Jinja2 templates (.j2) rendered with variable values before copying, for example nginx.conf.j2 with {{ server_name }} and {{ http_port }}
  • files/ — Static files copied unchanged, for example CA certificates, pre-built binaries
  • ansible.cfg — Project config overriding /etc/ansible/ansible.cfg: inventory path, remote_user, private_key_file, roles_path, host_key_checking=False
  • requirements.yml — External roles and collections; ansible-galaxy install -r requirements.yml installs everything

> [!TIP] Pin versions in requirements.yml to prevent unexpected upgrades.

Key concepts

Variable precedence
Ansible merges variables from many sources. Precedence order (lowest to highest): role defaults → inventory group_vars/all → inventory group_vars/ → inventory host_vars → playbook group_vars → playbook host_vars → task vars → extra vars (-e). Host vars override group vars; -e overrides everything.
ansible.cfg
Project-level configuration file. Ansible searches: ANSIBLE_CONFIG env var → ./ansible.cfg → ~/.ansible.cfg → /etc/ansible/ansible.cfg. Having ansible.cfg in the project root ties configuration to the project, avoiding surprises from system-wide settings.
Jinja2 templates
Ansible uses the Jinja2 templating engine. Variables are referenced with {{ variable_name }}. Conditionals: {% if condition %} ... {% endif %}. Loops: {% for item in list %} ... {% endfor %}. Templates in templates/ are rendered and deployed with the template module.
Dynamic inventory
Instead of static host files, inventory can be a Python script or plugin that queries a source of truth (AWS EC2, GCP, VMware, Netbox). Returns JSON with host groups and variables. Essential for cloud environments where hosts change dynamically.
requirements.yml
Declares external dependencies. Can list both collections and roles: --- collections: - name: amazon.aws version: ">=5.0.0" - name: community.general roles: - name: geerlingguy.nginx version: "3.2.0"

When to use it

  • Starting any new Ansible project — use this structure from day one
  • Onboarding team members — the standard layout is self-explanatory
  • Scaling a monolithic playbook that has outgrown a single file
  • Setting up CI/CD for infrastructure automation (test staging, then production)
  • Preparing for Red Hat RHCE/EX294 exam — this structure is the exam standard

Interview questions

  • Explain Ansible variable precedence and where you would define each type of variable.

Sign up free to read the full topic

More DevOps topics

Start free on Cariara · Coding problems · System design studio