SadServers
  • Scenarios
  • Labs
    All Labs Linux & Bash Web Servers Databases Data Processing Docker Kubernetes CI/CD Infrastructure as Code Tooling / Applications
  • Dashboard
  • Solutions
    For Individuals For Businesses
  • Ranking
  • Newsletter
  • Documentation
    FAQ Support Pro Accounts Pro+ Accounts Business Accounts Gift API CLI/TUI Privacy Troubleshooting Interviews
  • Blog
  • Pricing
  • Gift
    Gift Purchase Gift Redeem
  • About
Log In - Sign Up
  1. Labs
  2. Ansible
  3. Guide

Guide

Concepts and learning path

Troubleshooting

Failure modes and fixes

Cheatsheet

Commands to keep handy

Ansible guide

What Ansible does in production

Ansible pushes desired state to servers: install packages, drop config files, restart services, create users, harden SSH. It is agentless — only SSH and Python on the target (or Windows WinRM). Teams run playbooks from laptops, bastions, or CI (Jenkins, GitHub Actions). It complements Terraform, which provisions cloud resources; Ansible often configures VMs after Terraform creates them.

Core concepts

  • Control node — machine where you run ansible-playbook
  • Managed node / host — target server in inventory
  • Inventory — INI or YAML list of hosts and groups
  • Playbook — YAML file with plays (mapped to host groups)
  • Task — one module invocation with parameters
  • Module — unit of work (apt, copy, service)
  • Role — reusable bundle of tasks, handlers, templates, defaults
  • Handler — task run only when notified (e.g. restart nginx)

Minimal playbook

--- - name: Web servers hosts: web become: true tasks: - name: Install nginx ansible.builtin.apt: name: nginx state: present update_cache: true - name: Ensure nginx running ansible.builtin.service: name: nginx state: started enabled: true

How a run works

  1. Inventory — resolve host list and variables per group
  2. Facts — gather OS, network, mounts (setup module) unless disabled
  3. Tasks — execute in order; each module reports changed/ok/failed
  4. Handlers — flush at end of play if notified
  5. Idempotency — second run should show mostly ok, not changed

Inventory

Static inventory.ini or dynamic inventory scripts (cloud APIs). Groups like [web], [db]; children and group vars in group_vars/, host-specific in host_vars/. Connection details: ansible_host, ansible_user, ansible_ssh_private_key_file — see the SSH lab for keys and agent setup.

Become (privilege escalation)

become: true uses sudo (default) to run tasks as root. Requires passwordless sudo or --ask-become-pass. Misconfigured become is a frequent source of playbook failures on fresh VMs.

Variables and templates

Variables come from inventory, playbooks, roles, extra vars (-e), and facts. Templates use Jinja2 (.j2 files) rendered by the template module — typical for nginx, systemd unit files, and app config.

Roles and splitting large playbooks

A single playbook with hundreds of inline tasks becomes hard to read, test, and reuse. Production repos break work into roles — one role per logical concern (base OS hardening, nginx, application deploy, monitoring agent). Thin entry playbooks wire roles together; each role owns its tasks, files, and templates.

Recommended layout:

  • site.yml — top-level playbook; one play per host group, lists roles
  • roles/common/ — users, packages, sysctl, firewall baseline
  • roles/nginx/ — web server install, config, handlers
  • roles/myapp/ — app binaries, env files, service unit
  • group_vars/ and host_vars/ — environment-specific values

Standard role directories: tasks/, handlers/, templates/, files/, defaults/ (easy overrides), vars/ (higher precedence), and optional meta/main.yml for role dependencies. Put reusable defaults in defaults/main.yml; callers override in inventory or group_vars without editing the role.

--- # site.yml — keep plays short; delegate detail to roles - name: Web tier hosts: web become: true roles: - role: common - role: nginx - role: myapp - name: Database tier hosts: db become: true roles: - role: common - role: postgresql

When to extract a role: repeated task blocks across plays, a component owned by a different team, or anything you might reuse in another project. Use import_role / include_role for conditional or mid-play inclusion; list roles under roles: for the common case. Pin third-party roles from Galaxy in requirements.yml and vendor them in roles/ or document versions — same discipline as Terraform modules.

Collections and Galaxy

Modules live in collections (e.g. ansible.builtin, community.general). Install with ansible-galaxy collection install or pin in requirements.yml. Galaxy shares roles and collections — vendor with version pins for reproducible runs.

ansible.cfg

  • inventory — default inventory path
  • remote_user — SSH user
  • host_key_checking — SSH host key policy
  • retry_files_enabled — write .retry on failure

Learning resources

  • Ansible documentation — docs.ansible.com
  • Getting started — Getting started guide
  • Module index — Collection modules
  • Ansible Galaxy — galaxy.ansible.com
Troubleshooting →
SadServersSadServers

Real-world Linux and DevOps scenarios for hands-on learning and technical assessment.

Uptime Robot ratio (30 days)
Product
  • Scenarios
  • For Individuals
  • For Businesses
  • Pricing
Resources
  • FAQ
  • Blog
  • Newsletter
Company
  • About Us
  • Support
  • Privacy Policy
  • Terms of Service
  • Contact
Connect With Us
info@sadservers.com

Made in Canada 🇨🇦
Updated: 2026-06-13 16:06 UTC – 2d2950a