What Is Ansible? Concepts Every Software and DevOps Engineer Should Know

Prasad Waghamare

Installing a package on one Linux server takes less than a minute. Installing it correctly on fifty servers every month is a completely different problem.

As infrastructure grows, the work itself rarely becomes more difficult. What becomes difficult is performing the same task consistently across dozens or hundreds of machines without forgetting a step or introducing configuration differences. One server ends up running an older package version, another misses a firewall rule, and someone eventually spends hours debugging an issue caused by a manual change nobody documented.

Ansible was built to solve exactly that problem. Instead of logging into every server and repeating the same commands, you describe the state you want, and Ansible brings every machine to that state automatically.

This article explains the concepts behind Ansible before introducing the syntax. Once you understand these ideas, reading production playbooks and building your own automation becomes much easier.

What is Ansible, and why does it exist?

The problem with managing servers manually

Imagine your team manages a web application running on ten Linux servers. A security update is released, and every server needs the same package upgrade. You connect to the first server, install the update, and restart the service. Then you repeat the process on the second server, then the third.

Halfway through, someone interrupts you.

When you return, you are no longer sure which machines have already been updated. One server misses the change, another receives the wrong configuration file, and over time every machine starts behaving a little differently. Production still works, but your infrastructure is no longer consistent.

Those differences are called configuration drift, and they become increasingly difficult to manage as environments grow. The challenge is rarely the command itself. The challenge is executing the same change accurately on every server, every time.

Manual AdministrationWith Ansible
SSH into every server individuallyRun one playbook against all servers
It is easy to forget one server or apply slightly different changesEvery targeted server receives the same changes
Configuration differences gradually appear between serversServers remain consistent
Tracking who changed what is difficultPlaybooks are stored in Git, making changes easy to review, audit, and roll back
Repeating routine tasks consumes time and increases the chance of mistakes.Automation is repeatable, predictable, and can be executed safely whenever needed.

Why shell scripts eventually stop scaling

Most engineers solve this problem with shell scripts. Instead of typing commands repeatedly, they automate the process with Bash.

That works well for small environments. Then another engineer adds logging, someone else adds error handling, and the script starts supporting both Ubuntu and Red Hat. A few months later, what started as a twenty-line script has become hundreds of lines that nobody wants to modify.

The limitation is not Bash itself. Shell scripts describe how to perform every step. Ansible focuses on what the final system should look like, leaving the implementation details to its modules. That difference makes playbooks easier to read, maintain, and share across teams.

What configuration management actually means

Configuration management is the practice of keeping every server in a known, predictable state. Instead of relying on documentation or memory, the desired configuration is written as code and applied consistently across the infrastructure.

For example, instead of saying:

Install Nginx.

You describe the desired outcome:

  • Nginx should be installed.
  • The service should be running.
  • It should start automatically after every reboot.

If a server already matches that description, Ansible does nothing. If something is missing or configured incorrectly, Ansible changes only what is necessary. This behaviour, known as the desired state model, is the foundation of modern infrastructure automation.

Why Ansible became popular

Configuration management tools existed long before Ansible. Tools such as Puppet and Chef solved similar problems but required agents to run continuously on every managed machine.

Ansible took a simpler approach. It communicates over SSH, which Linux administrators already use every day. There is no permanent agent to install, automation is written in readable YAML, and getting started requires very little setup.

That simplicity made Ansible one of the most widely adopted automation tools in modern DevOps. Today, engineering teams use it to configure servers, deploy applications, install Kubernetes worker nodes, rotate certificates, automate operating system updates, and manage thousands of machines with the same playbook.

Before you write any Ansible

What you need installed

Every Ansible environment has two parts. The control node is the machine where Ansible runs. The managed nodes are the servers Ansible connects to and configures. Communication happens over SSH.

In most cases, the managed machines only need SSH access, Python installed, and a user with appropriate permissions. Unlike some configuration management tools, Ansible does not require a permanent agent running on every server. That makes it easier to introduce into existing environments without changing every machine first.

How Ansible communicates with servers

At a high level, every execution follows the same flow.

The control node reads your automation, connects to each server, executes only the required operations, and reports the result. Nothing happens manually once the playbook starts.

What an Ansible project actually looks like

Most Ansible projects follow a structure similar to this.

Each directory has a specific responsibility. inventory lists the servers, playbook.yml describes the automation, group_vars stores variables shared by groups, host_vars stores machine-specific values, and roles organize reusable automation. Keeping projects organized becomes increasingly important as your infrastructure grows.

The core building blocks

Every Ansible project is built from a few simple concepts. Once you understand how they fit together, most production playbooks become much easier to read.

Think of this as the execution pipeline Ansible follows every time you run a playbook.

Inventory: the machines Ansible manages

Ansible needs to know where your infrastructure lives. That information is stored in an inventory. A simple inventory might look like this.

Instead of targeting individual servers, you target logical groups such as web, database, or monitoring. As environments grow, inventories often represent staging, production, Kubernetes clusters, or multiple cloud regions. The inventory becomes the map of your infrastructure.

Modules: how Ansible performs work

Modules are the building blocks that perform individual operations. Need to install software? Use the package module. Need to create a user? Use the user module. Need to manage a service? Use the service module. For example:

Notice that you never tell Ansible how to install the package. You simply describe the desired result. The module handles the operating system details for you.

Tasks: one action at a time

A task is a single call to a module.

Every task should have one clear responsibility. Installing packages is one task, copying configuration files is another, and restarting services becomes a third. Small tasks make playbooks easier to understand, troubleshoot, and reuse.

Playbooks: putting everything together

A playbook combines multiple tasks into one repeatable workflow.

Instead of logging into every server, you run one command.

Ansible connects to every machine in the inventory, determines what needs to change, performs only those changes, and reports the result. That repeatability is what makes automation reliable.

Variables: keeping playbooks flexible

Hardcoding values quickly becomes difficult to maintain. Variables allow the same playbook to work across different environments. For example, instead of embedding a package version directly into every task, you define it once and reference it wherever needed. A production environment and a staging environment can use the same playbook while supplying different variable values. This keeps automation reusable instead of creating multiple copies of nearly identical playbooks.

Your first Ansible workflow

Running Ansible follows the same process every time.

  • Write an inventory describing the servers you want to manage.
  • Create a playbook that defines the desired state.
  • Validate the playbook syntax.
  • Execute the playbook against the inventory.
  • Review the execution results.

Example: Installing and Starting Nginx

The following playbook ensures that Nginx is installed, the service is running, and it starts automatically after every reboot on all servers in the webservers inventory group.

---

- name: Configure Nginx on web servers

  hosts: webservers

  become: true

  tasks:

    - name: Ensure Nginx is installed

      ansible.builtin.apt:

        name: nginx

        state: present

        update_cache: yes

    - name: Ensure Nginx service is running and enabled

      ansible.builtin.service:

        name: nginx

        state: started

        enabled: yes

 

Notice how the playbook never describes how to install Nginx. Instead, it describes the desired state:

  • Nginx should be installed.
  • The service should be running.
  • The service should start automatically after boot.

Ansible determines the actions needed to achieve that state.

Running the playbook

Once the inventory and playbook are ready, a typical workflow looks like this:

# Validate syntax

ansible-playbook -i inventory.ini playbook.yml --syntax-check

# Execute the playbook

ansible-playbook -i inventory.ini playbook.yml

During execution, Ansible reports the status of every task.

StatusMeaning
okThe system already matched the desired state.
changedAnsible made a change successfully.
failedThe task could not be completed.
skippedThe task did not meet its execution conditions.

Learning to read this output is just as important as writing playbooks. A successful execution is not measured by how many tasks ran. It is measured by whether every server reached the desired state without unexpected changes.

The concept beginners misunderstand most

Why idempotency matters

The biggest difference between Ansible and a shell script is not YAML. It is idempotency.An idempotent task produces the same result no matter how many times you run it. If Nginx is already installed, Ansible does not install it again. If a service is already running, Ansible leaves it alone.

- - - 

 name: Ensure Nginx is installed

  package:

    name: nginx

    state: present

 

The keyword here is present. You are not telling Ansible to install Nginx. You are telling it that Nginx should exist. Ansible checks the current state and performs only the changes needed to reach that state.

This makes playbooks safe to run repeatedly. Whether you execute the playbook once or ten times, the end result remains the same. That reliability is one of the reasons teams trust Ansible for routine deployments and server maintenance.

Making automation reusable

As infrastructure grows, copying the same tasks into multiple playbooks quickly becomes difficult to maintain. Ansible provides a few simple building blocks that help you reuse automation without duplicating code.

Variables

Variables let the same playbook work across different environments without hardcoding values such as package names, port numbers (for example, 8080), or application versions. You define these values once and reference them throughout the playbook, making the automation easier to maintain and reuse.

A staging environment and a production environment can use the same playbook while supplying different values.

Roles

A role groups everything needed for one component into a standard directory structure. Instead of maintaining one large playbook, you split automation into smaller, reusable units such as webserverdatabase, or monitoring.

Most production Ansible projects rely heavily on roles because they are easier to maintain, test, and share across teams.

Handlers

Some tasks should run only when another task changes something.

For example, copying a new Nginx configuration should restart the service, but only if the configuration file actually changed.

Handlers provide exactly that behavior, reducing unnecessary service restarts and making deployments more predictable.

Templates

Configuration files often differ between environments. A template lets you generate those files dynamically by inserting variables into a common template instead of maintaining multiple copies of nearly identical files.

Collections

Collections are packages of Ansible content published by the community or vendors. They include modules, roles, plugins, and documentation for platforms such as AWS, Azure, VMware, Kubernetes, and Cisco devices. Instead of writing everything from scratch, you can build on well-tested automation maintained by the community.

The hidden challenge of Ansible

Learning Ansible syntax is relatively easy. Keeping infrastructure consistent over time is the harder problem.

Configuration drift

Ansible assumes the playbook describes the desired state of your systems. If someone manually edits a server after automation has run, that server gradually drifts away from the rest of the environment.

The simplest way to avoid drift is to treat manual changes as temporary fixes. Once a change is verified, add it to the playbook so every server stays consistent.

Managing secrets

Playbooks often need sensitive information such as database passwords, API keys, or SSH credentials. Storing those values directly in YAML files is a security risk.

Ansible Vault encrypts sensitive variables so they can remain in version control without exposing confidential data. Teams commonly use Vault for secrets that must travel with the playbook, while larger organizations often integrate Ansible with dedicated secret management systems.

Knowing when not to use Ansible

Ansible is excellent for configuring servers and deploying applications, but it is not the right tool for every job.

When Terraform Is the Better Choice

If you are provisioning cloud infrastructure such as VPCs, EC2 instances, load balancers, or Kubernetes clusters, Terraform is usually the better choice, since it tracks infrastructure state and understands dependencies between resources. Ansible has no built-in concept of state; it simply checks the current condition of a system against the playbook each time it runs.

Ansible also isn't the best fit for scenarios that require complex orchestration with strict ordering across many interdependent systems, or environments that are almost entirely Windows-based, where other tools sometimes offer smoother native support.

ConsiderationAnsibleTerraform
Infrastructure approachMutable — existing servers are patched and updated in placeImmutable — outdated resources are destroyed and replaced, not modified
Best suited forTraditional applications running on long-lived servers or VMsCloud-native workloads such as Kubernetes, serverless functions, or auto-scaling groups
State managementNo built-in state tracking — simply applies the desired configuration each runMaintains a state file that tracks resources and their dependencies
Primary use caseConfiguring and maintaining what runs inside a serverProvisioning and managing the infrastructure itself

 

Using Both Tools Together

Once infrastructure exists, Ansible becomes an excellent tool for configuring the operating system, installing software, and deploying applications on top of it.

Many production environments use both tools together: Terraform creates the infrastructure, and Ansible configures what runs on it. This combination gives teams a clear separation between infrastructure provisioning and configuration management, with each tool doing the part it's best at, making both easier to maintain over time.

With inventories, modules, tasks, playbooks, and idempotency now familiar, you have the core vocabulary needed to read almost any production Ansible codebase, and to start writing your own.

Frequently asked questions

1. What are Ansible facts?

Ansible facts are system details — like OS type, IP address, memory, and hostname — that Ansible automatically collects from each managed node before running any tasks. They're stored as variables and commonly used for conditional logic (e.g., run a task only on Ubuntu servers) or to dynamically populate configuration files.

2. What is the difference between Ansible ad-hoc commands and playbooks?

An ad-hoc command runs a single task directly from the command line (e.g., ansible webservers -m ping) without writing a YAML file — useful for quick, one-off checks. A playbook, on the other hand, is a reusable, version-controlled YAML file that defines multi-step automation you can run repeatedly.

3. Can Ansible manage Windows servers?

Yes. Instead of SSH, Ansible connects to Windows machines using WinRM (Windows Remote Management), and uses Windows-specific modules such as win_service and win_package instead of the Linux modules like apt or service.

4. How do you do a dry run in Ansible?

You can preview what a playbook would change without actually applying anything by running it with the --check flag, often combined with --diff to see the exact file-level changes. This is different from --syntax-check, which only validates YAML syntax and doesn't simulate execution.

5. Is Ansible free to use?
Yes, Ansible (ansible-core and the community package) is fully open source and free. Red Hat sells a paid enterprise layer called Ansible Automation Platform (formerly Ansible Tower), which adds a web UI, role-based access control, job scheduling, and enterprise support on top of the free core tool.

Tags
DevOpsInfrastructure as CodeInfrastructure AutomationIaCPlatform EngineeringAnsibleConfiguration ManagementLinux Automation
Maximize Your Cloud Potential
Streamline your cloud infrastructure for cost-efficiency and enhanced security.
Discover how CloudOptimo optimize your AWS and Azure services.
Request a Demo