← Back to list

Kicking the tires on Ansible some more — part II

Real-World Demo & Ansible vs the Competition

Geert Kinthaert · 2026-06-13 21:36 · 0 claps · 5.8 min read
#ansible #configuration-management #ci-cd-pipeline
Open on Medium ↗
Wiki topics: BIZ · Business Strategy ☁️ · DevOps & Cloud

Kicking the tires on Ansible some more — part II

Real-World Demo & Ansible vs the Competition

From EC2 instances to configured web servers — and how Ansible stacks up against Puppet and Chef

In this blog post I perform a quick step-by-step walkthrough of a real Ansible deployment, and offer an honest look at when you should (and shouldn’t) choose Ansible.

Putting It Into Practice

Watching it work on real infrastructure is always the better option. This (very short) demo uses three Amazon Linux EC2 instances — a control node and two managed nodes and goes through the following workflow: setting up SSH access, installing Ansible, writing the configuration and inventory, building a playbook, and watching it configure both servers in a single run.

Step 1–4: Infrastructure Setup & SSH Access

Three EC2 instances are provisioned:

  • ansible-server: the Ansible control node where playbooks run
  • ansible-client1: managed node 1
  • ansible-client2: managed node 2

A security group (ansibleSG) allows inbound SSH (port 22) and HTTP (port 80). An SSH key pair (ansible.pem) is created for authentication. The PEM file is copied to the control node, and SSH connectivity to both clients is verified before anything else happens.

Steps 5–9: Install, Configure, and Run

With SSH access confirmed, the setup continues on the control node:

Step 5 — Install Ansible on the control node:

Step 6 — Write the ansible.cfg, pointing to the inventory file and SSH key:

Step 7 — Create the inventory file, grouping both clients under [webservers]:

Step 8 — Test Ansible connectivity with a ping:

A successful response:

Step 9 — Write the playbook. This is where the actual automation logic lives:

The playbook does three things in sequence: installs httpd (Apache) using the yum module, deploys a custom index.html using the copy module, and starts and enables the httpd service. Each task is named for readability in the output.

💡 Use Case: This three-task pattern — install, configure, start — is the backbone of almost every service deployment playbook. Need to deploy MySQL instead of Apache? Swap the package name, update the config files, change the service name. The structure stays identical.

💡 become: yes The become: yes directive at the play level tells Ansible to run all tasks with sudo (root) privileges on the managed nodes. Without it, tasks that need to install packages or write to system directories will fail with permission errors.

Steps 10–11: Run the Playbook & Verify

With the playbook written, a single command does the work across both servers simultaneously:

The output lists the tasks and status for each host:

  • “ok” — the task ran and found the desired state already in place (no change needed)
  • “changed” — the task ran and made a change on the managed node
  • “failed” — the task failed (execution stops by default)

The PLAY RECAP at the bottom gives a clean summary: both clients show ok=4, changed=3 — Ansible gathered facts (ok), installed httpd (changed), deployed the HTML file (changed), and started the service (changed). Zero failures.

A quick curl to each server’s private IP confirms both are serving the custom page:

💡 Idempotency in action: Run the same playbook again immediately. This time, all tasks show “ok” with changed=0. Nothing changed because the desired state is already in place. This is the behaviour you want: playbooks you can run repeatedly without side effects.

💡 Use Case: This exact pattern — push a playbook to configure web servers — is how many teams handle fleet-wide configuration updates. Update the index.html template, run the playbook, and every server in the [webservers] group is updated in minutes. No SSH-ing into individual boxes, no manual steps, no drift.

Ansible vs Puppet vs Chef

Ansible doesn’t exist in a vacuum. If you’re making a tooling decision, you’ll encounter Puppet and Chef. Understanding where each tool shines (and where it struggles) helps you make the right call for your team and situation.

Ansible — Simple, Agentless, Push-Based

Ansible’s defining characteristic is its simplicity. YAML playbooks are readable by people who’ve never touched Ansible before. The agentless, SSH-based architecture means zero footprint on managed nodes — you install Ansible once on a control node and you’re managing infrastructure within minutes. Its DevOps adoption is unmatched.

The trade-off: Ansible is task-oriented rather than state-enforcing. It runs when you tell it to, rather than continuously ensuring the desired state. Configuration drift — machines gradually diverging from their expected state — won’t be automatically corrected between playbook runs. At very large scale (thousands of nodes), the push-over-SSH model also shows performance limits.

Puppet — Declarative, Agent-Based, Continuous

Puppet operates on a fundamentally different model. Agents installed on every managed node periodically check in with the Puppet server, pull their configuration, and enforce it — continuously. This means configuration drift is automatically detected and corrected, making Puppet excellent for compliance-heavy environments where consistency must be continuously guaranteed.

The trade-off: Puppet’s custom DSL (Puppet Language) has a steeper learning curve than YAML, and the agent-based architecture adds operational overhead — you’re managing the agents as well as the infrastructure.

Chef — Developer-Centric, Powerful, Complex

Chef treats infrastructure as software. Cookbooks are written in Ruby, and Chef’s approach to configuration management feels like software development rather than sysadmin work. This makes it extraordinarily powerful and flexible for complex automation scenarios.

The trade-off: “you need to be excellent at Ruby” is no exaggeration. Chef has the highest learning curve of the three, and the agent-based architecture shares Puppet’s operational overhead. It shines in organizations where developer teams own their infrastructure automation.

💡 How to Choose: Start with Ansible if: your team is small, you want a fast ramp-up time, or you’re deploying applications rather than enforcing compliance baselines. Consider Puppet if: you’re running a large enterprise environment where continuous compliance enforcement is critical. Consider Chef if: you have a strong engineering culture, complex automation needs, and Ruby expertise on the team.

💡 Real-World Nuance: Many organizations use Ansible and another tool together. Terraform provisions the infrastructure, Ansible configures it. Or Puppet enforces baseline OS configuration while Ansible handles application deployments. The tools aren’t mutually exclusive.

Wrapping Up

Ansible is the most accessible automation tool in this space. It scales from a few servers to a thousand.

Get comfortable with ansible.cfg, inventory, variables, modules, roles, and handlers (the building blocks everything else is built from) and the path from “I can run a playbook” to “I have a production-grade Ansible setup” is just a matter of time.

The comparison with Puppet and Chef is a reminder that tools are just means to an end, and what you use may not be your choice anyway if you work in an organization. Ansible is an excellent starting point for most teams, but the right choice depends on your scale, your compliance requirements, and your team’s existing skill set. Using the tool that lets your team build reliable infrastructure should be the goal


메타데이터
post_id
0ed7c5a00bb4
slug
kicking-the-tires-on-ansible-some-more-part-ii-0ed7c5a00bb4
url
https://medium.com/@gkinthaert/kicking-the-tires-on-ansible-some-more-part-ii-0ed7c5a00bb4
canonical_url
https://medium.com/@gkinthaert/kicking-the-tires-on-ansible-some-more-part-ii-0ed7c5a00bb4
author_url
https://medium.com/@gkinthaert
status
ok
fetched_at
2026-06-14 11:28:49