{"id":165310,"date":"2026-04-07T18:39:58","date_gmt":"2026-04-07T15:39:58","guid":{"rendered":"https:\/\/computingforgeeks.com\/ansible-automation-guide\/"},"modified":"2026-04-14T12:24:48","modified_gmt":"2026-04-14T09:24:48","slug":"ansible-automation-guide","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/ansible-automation-guide\/","title":{"rendered":"Ansible Automation Guide: From Basics to Production"},"content":{"rendered":"<p>Managing a handful of servers by hand is fine. Managing fifty, or five hundred, with SSH and bash scripts gets old fast. Ansible turns infrastructure work into repeatable, version-controlled code that runs the same way every time. No agents to install, no master server to babysit, no proprietary language to learn.<\/p>\n\n<p>This page is a structured learning path. Whether you&#8217;re writing your first playbook or building production-grade automation across hundreds of nodes, every topic links to a focused, tested guide. Start from the top if you&#8217;re new, or jump to the section that matches where you are. Each linked article has been tested on real systems with real output, not theoretical examples.<\/p>\n\n<p><em>Updated <strong>April 2026<\/strong> for ansible-core 2.20.4 and ansible 13.5.0. All linked guides tested on Rocky Linux 10.1 and Ubuntu 24.04. 17 articles published in the series.<\/em><\/p>\n\n\n<h2 class=\"wp-block-heading\">What Makes Ansible Different<\/h2>\n\n\n<p>Ansible connects to your servers over SSH, runs tasks, and disconnects. No daemon running on managed nodes, no database tracking state, no PKI infrastructure to maintain. If you can SSH into a box, Ansible can manage it.<\/p>\n\n<p>Playbooks are written in YAML. That&#8217;s a deliberate choice. A junior sysadmin can read a playbook and understand what it does without learning a DSL. Compare that to Puppet manifests or Chef recipes, which require understanding Ruby-based syntax before you can be productive.<\/p>\n\n<p>Every Ansible module is idempotent by design. Run a playbook once or ten times, the result is the same. The <code>apt<\/code> module doesn&#8217;t reinstall a package that&#8217;s already present. The <code>lineinfile<\/code> module doesn&#8217;t duplicate entries. This means you can run playbooks as a form of drift detection: if nothing changes, your systems match your code.<\/p>\n\n<p>The module library covers nearly everything: package management, file manipulation, user accounts, firewall rules, cloud provisioning, container orchestration, network devices. For a detailed comparison with Chef, Puppet, and SaltStack, see <a href=\"https:\/\/computingforgeeks.com\/ansible-vs-chef-puppet-salt\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible vs Chef vs Puppet vs Salt<\/a>.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Getting Started<\/h2>\n\n\n<p>These guides cover the fundamentals. Work through them in order if you&#8217;re new to Ansible, or pick the ones you need if you already have some experience. Each one builds on concepts from the previous articles.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Install Ansible<\/h3>\n\n\n<p>Before anything else, you need a working Ansible installation on your control node. The control node is the machine you run playbooks from (your laptop, a jump box, a CI runner). Managed nodes only need Python and SSH.<\/p>\n\n<p>On Rocky Linux 10, ansible-core 2.16.14 is available directly from the package manager. For the latest features (ansible 13.5.0 with ansible-core 2.20.4), install via pip with Python 3.12.<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>ansible --version<\/code><\/pre>\n\n\n<p>A working installation shows the core version, config file path, and Python interpreter:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>ansible [core 2.16.14]\n  config file = \/etc\/ansible\/ansible.cfg\n  configured module search path = ['\/root\/.ansible\/plugins\/modules']\n  ansible python module location = \/usr\/lib\/python3.12\/site-packages\/ansible\n  executable location = \/usr\/bin\/ansible\n  python version = 3.12.8<\/code><\/pre>\n\n\n<p>Full installation walkthrough for multiple distros and methods:<\/p>\n\n<ul>\n<li><strong>RHEL family<\/strong> &#8211; <a href=\"https:\/\/computingforgeeks.com\/install-ansible-rocky-linux-ubuntu\/\" target=\"_blank\" rel=\"noreferrer noopener\">Install Ansible on Rocky Linux and Ubuntu<\/a><\/li>\n<li><strong>Debian<\/strong> &#8211; <a href=\"https:\/\/computingforgeeks.com\/install-ansible-debian\/\" target=\"_blank\" rel=\"noreferrer noopener\">Install Ansible on Debian<\/a><\/li>\n<li><strong>General Linux<\/strong> &#8211; <a href=\"https:\/\/computingforgeeks.com\/install-configure-ansible-linux\/\" target=\"_blank\" rel=\"noreferrer noopener\">Install and Configure Ansible on Linux<\/a><\/li>\n<\/ul>\n\n\n<h3 class=\"wp-block-heading\">Ad-Hoc Commands<\/h3>\n\n\n<p>Ad-hoc commands let you run one-off tasks across your inventory without writing a playbook. Restarting a service on 20 servers, checking disk space everywhere, copying a file to a group of hosts. Think of them as Ansible&#8217;s equivalent of a quick SSH loop, but with module-level intelligence and parallel execution.<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>ansible webservers -m service -a \"name=nginx state=restarted\"<\/code><\/pre>\n\n\n<p>That single command restarts Nginx on every host in the <code>webservers<\/code> group, in parallel, with proper service management (not a raw <code>kill<\/code> and start).<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-ad-hoc-commands\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Ad-Hoc Commands<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Inventory Management<\/h3>\n\n\n<p>The inventory file tells Ansible which servers exist and how to group them. A simple INI file works for small environments. As you scale, you&#8217;ll move to YAML inventories, group variables, and eventually dynamic inventories that pull from cloud APIs.<\/p>\n\n<p>Getting inventory structure right early saves significant refactoring later. A well-organized inventory with logical groups (<code>webservers<\/code>, <code>databases<\/code>, <code>staging<\/code>, <code>production<\/code>) makes playbooks cleaner and limits the blast radius of mistakes.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-inventory-management\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Inventory Management<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Your First Playbook<\/h3>\n\n\n<p>Playbooks are where Ansible becomes powerful. A playbook is a YAML file describing the desired state of your systems: packages installed, services running, config files in place, firewall rules applied. You declare <em>what<\/em> should be true, and Ansible figures out the steps to get there.<\/p>\n\n<p>A playbook that installs and configures Nginx with a custom virtual host might look like this:<\/p>\n\n\n<pre class=\"wp-block-code code\"><code>---\n- name: Configure web servers\n  hosts: webservers\n  become: true\n  tasks:\n    - name: Install Nginx\n      ansible.builtin.dnf:\n        name: nginx\n        state: present\n\n    - name: Deploy virtual host config\n      ansible.builtin.template:\n        src: templates\/vhost.conf.j2\n        dest: \/etc\/nginx\/conf.d\/app.conf\n      notify: Restart Nginx\n\n  handlers:\n    - name: Restart Nginx\n      ansible.builtin.service:\n        name: nginx\n        state: restarted<\/code><\/pre>\n\n\n<p>Even without Ansible experience, you can read that and understand what it does. That readability is one of Ansible&#8217;s strongest selling points.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-playbook-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Playbook Tutorial<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Variables and Facts<\/h3>\n\n\n<p>Variables make playbooks reusable. Instead of hardcoding package names, paths, and port numbers, you define them as variables and override per host, per group, or per environment. Ansible also gathers &#8220;facts&#8221; automatically: OS family, IP addresses, memory, disk layout. You can use these facts in conditionals and templates to write playbooks that adapt to each server&#8217;s characteristics.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-variables-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Variables: Facts, Defaults, and Custom Setup<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Conditionals and Loops<\/h3>\n\n\n<p>Not every task should run on every host. The <code>when<\/code> keyword lets you skip tasks based on facts, variables, or the results of previous tasks. Install <code>httpd<\/code> on RHEL, <code>apache2<\/code> on Debian. Open port 443 only if SSL is enabled. Loops let you iterate over lists of packages, users, or configuration items without duplicating task definitions.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-conditionals-loops-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Conditionals and Loops<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Handlers<\/h3>\n\n\n<p>Handlers solve a common problem: you only want to restart a service when its configuration actually changed. If you update <code>nginx.conf<\/code> and nothing is different from what&#8217;s already on disk, Ansible skips the task and the handler never fires. This prevents unnecessary service restarts during routine playbook runs.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Jinja2 Templating<\/h3>\n\n\n<p>Templates turn static config files into dynamic ones. A single <code>nginx.conf.j2<\/code> template can generate different configurations for each server based on variables: different worker counts based on CPU cores, different upstream blocks for each environment, different SSL certificate paths. Jinja2 is the same templating engine used by Flask and Django, so the syntax is well-documented and widely understood.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-jinja2-templates-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Jinja2 Templating<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Ansible Roles<\/h3>\n\n\n<p>Roles bring structure to complex automation. Instead of one massive playbook with 200 tasks, you organize related tasks, templates, variables, and handlers into self-contained roles. A <code>nginx<\/code> role, a <code>postgresql<\/code> role, a <code>security_baseline<\/code> role. Each can be developed, tested, and reused independently. Ansible Galaxy hosts thousands of community roles you can use as starting points.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-roles-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Roles Tutorial<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Debugging Playbooks<\/h3>\n\n\n<p>When a playbook fails (and it will), you need to know how to investigate. The <code>debug<\/code> module prints variable values during execution. Increasing verbosity with <code>-v<\/code>, <code>-vv<\/code>, or <code>-vvv<\/code> shows connection details, module arguments, and raw responses. The <code>--check<\/code> flag does a dry run. The <code>--diff<\/code> flag shows what would change in files. Mastering these tools turns a 30-minute debugging session into a 2-minute one.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Intermediate Skills<\/h2>\n\n\n<p>Once you&#8217;re comfortable writing playbooks and roles, these topics take your automation to the next level. This is where Ansible stops being &#8220;a better SSH loop&#8221; and becomes a real configuration management platform.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Ansible Vault<\/h3>\n\n\n<p>Vault encrypts sensitive data (passwords, API keys, certificates) so you can commit them to version control safely. No more passing secrets via environment variables or keeping them in plaintext files outside the repo. Vault integrates directly into playbooks, so encrypted variables are decrypted at runtime without extra tooling.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-vault-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Vault Tutorial<\/a> | Quick reference: <a href=\"https:\/\/computingforgeeks.com\/ansible-vault-cheat-sheet-reference-guide\/\" target=\"_blank\" rel=\"noreferrer noopener\">Vault Cheat Sheet<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Dynamic Inventory<\/h3>\n\n\n<p>Static inventory files don&#8217;t work when your infrastructure is elastic. In AWS, GCP, or OpenStack, servers come and go. Dynamic inventory scripts query your cloud provider&#8217;s API and build the inventory at runtime. Ansible includes inventory plugins for all major cloud platforms, VMware, and container orchestrators.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-dynamic-inventory-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Dynamic Inventory<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Collections<\/h3>\n\n\n<p>Collections are Ansible&#8217;s packaging format for distributing modules, roles, and plugins together. Since Ansible 2.10, most modules live in collections rather than the core package. You install them with <code>ansible-galaxy collection install<\/code> and reference modules by their fully qualified name (like <code>ansible.builtin.copy<\/code> or <code>community.postgresql.postgresql_db<\/code>). Understanding collections is essential for working with current Ansible versions.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Molecule Testing<\/h3>\n\n\n<p>Molecule provides a framework for testing Ansible roles in isolation. It spins up containers or VMs, runs your role, then runs verification tests (usually with Testinfra or Ansible itself). Catching bugs in a disposable container is far better than discovering them on production servers at 2 AM. Molecule integrates with CI\/CD pipelines so every commit to a role triggers automated testing.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Filters and Data Manipulation<\/h3>\n\n\n<p>Jinja2 filters transform data within playbooks. Parse JSON output from API calls, extract specific fields from complex data structures, format strings, calculate values, manipulate IP addresses. Filters like <code>json_query<\/code>, <code>regex_replace<\/code>, <code>ipaddr<\/code>, and <code>combine<\/code> are used constantly in production playbooks. Learning the common filters saves you from writing custom modules for simple data transformations.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Error Handling and Recovery<\/h3>\n\n\n<p>Production playbooks need to handle failures gracefully. The <code>block<\/code>\/<code>rescue<\/code>\/<code>always<\/code> pattern lets you try a set of tasks, catch failures, and run cleanup regardless of outcome. The <code>ignore_errors<\/code> directive, <code>failed_when<\/code> conditions, and <code>retries<\/code> with <code>until<\/code> loops give you fine-grained control over how failures are handled. The difference between a playbook that works in the lab and one that survives production is usually error handling.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Docker with Ansible<\/h3>\n\n\n<p>Ansible manages Docker containers, images, networks, and volumes through the <code>community.docker<\/code> collection. Build images, deploy containers with specific configurations, manage Docker Compose stacks, and orchestrate multi-container applications. This is particularly useful when you need to manage Docker across a fleet of hosts, not just a single development machine.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/how-to-manage-docker-containers-with-ansible\/\" target=\"_blank\" rel=\"noreferrer noopener\">Manage Docker Containers with Ansible<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Ansible Cheat Sheet<\/h3>\n\n\n<p>A compact reference covering every common command, module pattern, and playbook keyword. Keep it open in a tab while working. It covers ad-hoc syntax, playbook structure, vault commands, Galaxy usage, and debugging flags in a scannable format.<\/p>\n\n<p>Full reference: <a href=\"https:\/\/computingforgeeks.com\/ansible-cheat-sheet\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Cheat Sheet<\/a><\/p>\n\n\n<h2 class=\"wp-block-heading\">Advanced Topics<\/h2>\n\n\n<p>These topics are for engineers running Ansible at scale or integrating it into complex workflows. If you&#8217;re automating across hundreds of hosts, building custom modules, or implementing zero-downtime deployments, this section covers what you need.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Event-Driven Ansible<\/h3>\n\n\n<p>Event-Driven Ansible (EDA) reacts to events from monitoring tools, webhooks, or message queues and triggers playbook runs automatically. A Prometheus alert fires, EDA catches it, runs a remediation playbook. A new VM comes online, EDA detects it and applies the baseline configuration. This shifts Ansible from &#8220;push on demand&#8221; to &#8220;respond in real time.&#8221;<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/event-driven-ansible-eda-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Event-Driven Ansible (EDA) Tutorial<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Custom Modules<\/h3>\n\n\n<p>When the 6,000+ existing modules don&#8217;t cover your use case, you write your own. Custom modules are Python scripts that follow Ansible&#8217;s module interface. They receive arguments as JSON, perform work, and return structured results. If you&#8217;re managing in-house applications or proprietary hardware, custom modules give you first-class Ansible integration instead of relying on <code>shell<\/code> and <code>command<\/code> tasks.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Zero-Downtime Deployments<\/h3>\n\n\n<p>Rolling updates, canary deployments, blue-green switches. Ansible&#8217;s <code>serial<\/code> keyword controls how many hosts are updated simultaneously. Combined with load balancer drain commands and health check verification, you can deploy application updates across a cluster without dropping a single request. The strategy depends on your architecture, but Ansible provides the building blocks.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Compliance Scanning<\/h3>\n\n\n<p>Ansible can enforce compliance policies across your fleet. CIS benchmarks, STIGs, PCI-DSS requirements. Write playbooks that check (and optionally remediate) compliance settings: password policies, SSH hardening, filesystem permissions, audit logging. The <code>--check<\/code> mode generates reports without making changes, which is exactly what auditors want to see.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Scaling Ansible<\/h3>\n\n\n<p>Managing 10 servers and managing 10,000 servers requires different approaches. Connection plugins, SSH pipelining, <code>mitogen<\/code> for faster execution, fact caching with Redis, pull-mode with <code>ansible-pull<\/code>, and AWX\/AAP for centralized management with RBAC and scheduling. Understanding these scaling strategies is the difference between a 5-minute playbook run and a 5-hour one.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Kubernetes with Ansible<\/h3>\n\n\n<p>The <code>kubernetes.core<\/code> collection lets Ansible manage Kubernetes resources: deployments, services, configmaps, secrets, namespaces. This fills the gap between Terraform (which provisions the cluster) and Helm (which packages applications). Ansible can bootstrap a cluster, deploy applications, and configure cluster-level settings in a single workflow.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Performance Tuning<\/h3>\n\n\n<p>Default Ansible settings are conservative. Bumping <code>forks<\/code> from 5 to 50, enabling SSH pipelining, using <code>gather_facts: false<\/code> when you don&#8217;t need facts, switching to the <code>free<\/code> strategy, and caching facts between runs can dramatically reduce execution time. For large inventories, these optimizations compound.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Integration Guides<\/h2>\n\n\n<p>Ansible rarely works alone. These guides show how to connect it with other tools in your stack, from infrastructure provisioning to monitoring to CI\/CD pipelines.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Terraform + Ansible<\/h3>\n\n\n<p>Terraform provisions infrastructure (VMs, networks, load balancers), then hands off to Ansible for configuration management. Terraform creates the servers, Ansible makes them useful. This combination is one of the most common patterns in modern infrastructure automation, and getting the handoff right (dynamic inventory from Terraform state, or provisioner integration) determines how smooth the workflow is.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/terraform-ansible-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Terraform and Ansible Tutorial<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Ansible + Proxmox<\/h3>\n\n\n<p>The <code>community.general.proxmox<\/code> modules let Ansible create, clone, start, stop, and configure Proxmox VMs and containers. Useful for homelab automation, development environments, and private cloud setups where Proxmox is the hypervisor.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-proxmox-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible + Proxmox Tutorial<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Ansible + Windows Server<\/h3>\n\n\n<p>Ansible manages Windows servers over WinRM instead of SSH. The <code>ansible.windows<\/code> collection provides modules for IIS, Active Directory, Windows features, registry, services, and PowerShell execution. Configuration is slightly different from Linux (WinRM setup, credential handling), but once connected, the playbook experience is similar.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/ansible-windows-server-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible for Windows Server<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Ansible + GitLab CI\/CD<\/h3>\n\n\n<p>Running Ansible from a GitLab pipeline turns your infrastructure code into a proper CI\/CD workflow. Merge requests trigger <code>--check<\/code> mode for review, merges to main trigger the actual deployment. Combined with Ansible Vault for secrets and GitLab&#8217;s protected variables, this gives you auditable, reviewable infrastructure changes.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Ansible + Grafana\/Prometheus<\/h3>\n\n\n<p>Automate the deployment and configuration of your monitoring stack. Ansible installs Prometheus, configures scrape targets from inventory, deploys Grafana with provisioned dashboards and data sources, and sets up Alertmanager rules. When your monitoring infrastructure is defined in code, rebuilding it after a disaster takes minutes instead of hours.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Real-World Projects<\/h2>\n\n\n<p>Theory is useful, but production experience is what makes the difference. These project-based guides walk through complete automation scenarios you&#8217;ll encounter in real infrastructure work.<\/p>\n\n\n<h3 class=\"wp-block-heading\">LAMP\/LEMP Stack Deployment<\/h3>\n\n\n<p>A classic first project: deploy a complete web application stack (Linux, Nginx, MySQL\/MariaDB, PHP) with Ansible. One playbook provisions the entire stack, configures virtual hosts, sets up database credentials, and deploys application code. It covers the full loop from bare server to running application.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Server Hardening<\/h3>\n\n\n<p>A hardening playbook that applies security baselines across your fleet: SSH key-only authentication, fail2ban, unattended security updates, firewall rules, kernel hardening parameters, audit logging. Run it on every new server as part of provisioning. Covers both RHEL and Debian family differences.<\/p>\n\n\n<h3 class=\"wp-block-heading\">User and Group Management<\/h3>\n\n\n<p>Managing user accounts, SSH keys, sudo rules, and group memberships across dozens of servers is painful without automation. An Ansible role handles all of it from a single source of truth: a YAML file listing users, their keys, their groups, and which servers they should have access to.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/manage-users-and-groups-on-linux-using-ansible\/\" target=\"_blank\" rel=\"noreferrer noopener\">Manage Users and Groups on Linux Using Ansible<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Database Management<\/h3>\n\n\n<p>Automate PostgreSQL or MySQL\/MariaDB deployments: install the server, configure authentication, create databases and users, set replication, manage backups. The <code>community.postgresql<\/code> and <code>community.mysql<\/code> collections provide dedicated modules that handle database operations properly, including idempotent user creation and privilege management.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/how-to-manage-postgresql-database-with-ansible\/\" target=\"_blank\" rel=\"noreferrer noopener\">Manage PostgreSQL Database with Ansible<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">SSL Certificate Management<\/h3>\n\n\n<p>Generate and distribute SSL certificates across your infrastructure with Ansible. Whether you&#8217;re using Let&#8217;s Encrypt for public services or self-signed certificates for internal communication, automating certificate lifecycle prevents the dreaded expired-certificate outage.<\/p>\n\n<p>Full guide: <a href=\"https:\/\/computingforgeeks.com\/generate-openssl-self-signed-certificates-with-ansible\/\" target=\"_blank\" rel=\"noreferrer noopener\">Generate OpenSSL Self-Signed Certificates with Ansible<\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Backup Automation<\/h3>\n\n\n<p>Automate backup jobs across your fleet: database dumps, config file archives, log rotation, offsite transfer to object storage. A well-designed backup role handles scheduling via cron, retention policies, compression, and notification on failure. The role should be idempotent so running it again doesn&#8217;t create duplicate cron entries.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Quick Reference: Ansible CLI Commands<\/h2>\n\n\n<p>These are the core command-line tools you&#8217;ll use daily. For the full reference with examples and flags, see the <a href=\"https:\/\/computingforgeeks.com\/ansible-cheat-sheet\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible Cheat Sheet<\/a>.<\/p>\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Command<\/th><th>Purpose<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><code>ansible<\/code><\/td><td>Run ad-hoc commands on hosts<\/td><td><code>ansible all -m ping<\/code><\/td><\/tr><tr><td><code>ansible-playbook<\/code><\/td><td>Execute a playbook<\/td><td><code>ansible-playbook site.yml<\/code><\/td><\/tr><tr><td><code>ansible-galaxy<\/code><\/td><td>Install roles and collections<\/td><td><code>ansible-galaxy install geerlingguy.nginx<\/code><\/td><\/tr><tr><td><code>ansible-vault<\/code><\/td><td>Encrypt\/decrypt sensitive files<\/td><td><code>ansible-vault encrypt secrets.yml<\/code><\/td><\/tr><tr><td><code>ansible-inventory<\/code><\/td><td>Display or dump inventory data<\/td><td><code>ansible-inventory --list<\/code><\/td><\/tr><tr><td><code>ansible-doc<\/code><\/td><td>View module documentation locally<\/td><td><code>ansible-doc ansible.builtin.copy<\/code><\/td><\/tr><tr><td><code>ansible-config<\/code><\/td><td>View and validate configuration<\/td><td><code>ansible-config dump --changed<\/code><\/td><\/tr><tr><td><code>ansible-pull<\/code><\/td><td>Pull playbooks from git and run locally<\/td><td><code>ansible-pull -U https:\/\/repo.git<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">How Ansible Works: Architecture Overview<\/h2>\n\n\n<p>Understanding the execution flow helps you debug problems and write better playbooks.<\/p>\n\n<p>The <strong>control node<\/strong> is where you run Ansible. It reads your inventory to determine which hosts to target, parses the playbook to build a task list, then connects to each <strong>managed node<\/strong> over SSH (or WinRM for Windows). For each task, Ansible copies a small Python script (the module) to the managed node, executes it, captures the JSON result, and removes the script. The control node collects results from all hosts and reports success or failure.<\/p>\n\n<p>The key components in this flow:<\/p>\n\n<ul>\n<li><strong>Inventory<\/strong> &#8211; Defines hosts and groups. Can be static (INI\/YAML files) or dynamic (scripts\/plugins that query cloud APIs)<\/li>\n<li><strong>Playbook<\/strong> &#8211; YAML file describing desired state. Contains plays, which target host groups, which contain tasks<\/li>\n<li><strong>Modules<\/strong> &#8211; Self-contained units of work (install a package, copy a file, manage a service). Over 6,000 available across collections<\/li>\n<li><strong>Facts<\/strong> &#8211; System information gathered from each managed node at the start of a play (OS, IPs, hardware, mounts)<\/li>\n<li><strong>Plugins<\/strong> &#8211; Extend Ansible&#8217;s behavior: connection plugins (SSH, WinRM), callback plugins (output formatting), lookup plugins (external data sources)<\/li>\n<li><strong>Handlers<\/strong> &#8211; Tasks that run only when notified by other tasks. Used for service restarts after config changes<\/li>\n<\/ul>\n\n<p>Execution order is deterministic: tasks run top to bottom, one at a time, across all targeted hosts in parallel (controlled by the <code>forks<\/code> setting). Handlers run at the end of each play, after all tasks complete. This predictability is what makes Ansible reliable in production.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Ansible Concepts for Beginners<\/h2>\n\n\n<p>If you&#8217;re coming from shell scripting or manual administration, these are the mental model shifts that matter most.<\/p>\n\n<p><strong>Declarative, not imperative.<\/strong> You don&#8217;t write &#8220;run <code>apt install nginx<\/code>.&#8221; You write &#8220;the package <code>nginx<\/code> should be <code>present<\/code>.&#8221; Ansible checks if it&#8217;s already there and only acts if needed. This is why playbooks are safe to run repeatedly.<\/p>\n\n<p><strong>Push, not pull.<\/strong> By default, you push configuration from the control node to managed nodes on demand. No agent polling a server every 30 minutes. You decide when changes deploy. (Pull mode exists via <code>ansible-pull<\/code> for specific use cases, like auto-configuring new cloud instances at boot.)<\/p>\n\n<p><strong>Inventory is everything.<\/strong> A well-structured inventory with logical groups, group variables, and host variables is what separates a maintainable Ansible setup from a messy one. Spend time getting this right early.<\/p>\n\n<p>For a broader introduction to Ansible&#8217;s philosophy and design principles, see our <a href=\"https:\/\/computingforgeeks.com\/introduction-to-ansible-automation-on-linux-understanding-ansible\/\" target=\"_blank\" rel=\"noreferrer noopener\">Introduction to Ansible Automation on Linux<\/a>.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Choosing How to Install: Package Manager vs Pip<\/h2>\n\n\n<p>This comes up often enough that it deserves its own section.<\/p>\n\n<p>On Rocky Linux 10, <code>dnf install ansible-core<\/code> gives you version 2.16.14. Stable, tested with the OS Python (3.12), and covered by RHEL security advisories. This is the right choice for most production control nodes.<\/p>\n\n<p>Installing via pip (<code>pip install ansible<\/code>) gives you ansible 13.5.0 with ansible-core 2.20.4. More modules, newer features, faster bug fixes. Use this when you need a specific collection that requires a newer core version, or when you want to run the same Ansible version across different OS platforms.<\/p>\n\n\n<pre class=\"wp-block-code code\"><code># Package manager (Rocky Linux 10)\nsudo dnf install -y ansible-core\n\n# Pip (any Linux with Python 3.12+)\npip install --user ansible<\/code><\/pre>\n\n\n<p>Both methods are covered in detail in the <a href=\"https:\/\/computingforgeeks.com\/install-ansible-rocky-linux-ubuntu\/\" target=\"_blank\" rel=\"noreferrer noopener\">installation guide<\/a>. Pick one and be consistent across your team.<\/p>\n\n\n<h2 class=\"wp-block-heading\">Where to Go from Here<\/h2>\n\n\n<p>If you&#8217;re starting from scratch, begin with <a href=\"https:\/\/computingforgeeks.com\/install-ansible-rocky-linux-ubuntu\/\" target=\"_blank\" rel=\"noreferrer noopener\">installation<\/a>, then work through <a href=\"https:\/\/computingforgeeks.com\/ansible-ad-hoc-commands\/\" target=\"_blank\" rel=\"noreferrer noopener\">ad-hoc commands<\/a>, <a href=\"https:\/\/computingforgeeks.com\/ansible-inventory-management\/\" target=\"_blank\" rel=\"noreferrer noopener\">inventory<\/a>, and your <a href=\"https:\/\/computingforgeeks.com\/ansible-playbook-tutorial\/\" target=\"_blank\" rel=\"noreferrer noopener\">first playbook<\/a>. That sequence gives you working knowledge in a single afternoon.<\/p>\n\n<p>For the official module index and full documentation, the <a href=\"https:\/\/docs.ansible.com\/ansible\/latest\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ansible documentation<\/a> is the canonical reference. The <a href=\"https:\/\/docs.ansible.com\/ansible\/latest\/collections\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">collections index<\/a> lists every available module organized by vendor and platform.<\/p>\n\n<p>This page is updated as new guides are published. Bookmark it and check back. Every linked article is tested on real infrastructure with verified output, not recycled documentation.<\/p>\n\n\n<p class=\"wp-block-paragraph\">For accelerating Ansible playbook development with AI, see <a href=\"https:\/\/computingforgeeks.com\/ai-coding-agents-devops-terraform-ansible-kubernetes\/\">Using AI Coding Agents for DevOps: Terraform, Ansible, and Kubernetes<\/a>.<\/p>\n\n\n","protected":false},"excerpt":{"rendered":"<p>Managing a handful of servers by hand is fine. Managing fifty, or five hundred, with SSH and bash scripts gets old fast. Ansible turns infrastructure work into repeatable, version-controlled code that runs the same way every time. No agents to install, no master server to babysit, no proprietary language to learn. This page is a &#8230; <a title=\"Ansible Automation Guide: From Basics to Production\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/ansible-automation-guide\/\" aria-label=\"Read more about Ansible Automation Guide: From Basics to Production\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":166103,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[606,329,35913,299,50],"tags":[314,212],"cfg_series":[39825],"class_list":["post-165310","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ansible","category-automation","category-devops","category-how-to","category-linux-tutorials","tag-ansible","tag-automation","cfg_series-ansible-mastery"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/165310","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=165310"}],"version-history":[{"count":2,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/165310\/revisions"}],"predecessor-version":[{"id":166085,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/165310\/revisions\/166085"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/166103"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=165310"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=165310"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=165310"},{"taxonomy":"cfg_series","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/cfg_series?post=165310"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}