HomeSource & deliveryConfig Mgmt & Ansible
Day 14 · 15 — managing the configuration of a whole fleet

Configuration Management & Ansible

A DevOps engineer rarely manages one server — they manage hundreds or thousands, and every one of them needs the same patches, packages, and settings. Doing that by hand, or with fragile per-server scripts, does not scale. This chapter rebuilds Days 14 and 15 into a workshop: first you understand what configuration management is and why Ansible became the tool everyone uses, then you get hands-on installing Ansible and writing your first playbooks and roles, then you get quizzed the way an interviewer would, and finally you face the senior scenarios of running config management on a real fleet.

① Theory② Lab③ Interview Q&A④ Scenario drills
Day 14 · Configuration Management — Puppet vs Ansible Day 15 · Ansible Zero-to-Hero — the hands-on project
⚡ The whole of configuration management in one mental model

Configuration management is how a DevOps engineer manages the configuration of many servers at once. Every server needs the same things kept in order — upgrades, security patches, default installations — and once you have hundreds or thousands of them, logging into each one is impossible. Configuration management is the discipline of describing the state you want and having a tool enforce it across the whole fleet. The tool almost everyone uses is Ansible, because it is agentless (nothing to install on the servers you manage), push-based (you run it from one place and it configures everything), and written in plain YAML.

Control nodeyour laptop + a playbook server (Ubuntu) server (CentOS) server (Windows) … hundreds more push over SSH · no agent on the servers
Push, agentless, from one place. You describe the desired state once, and Ansible pushes it out over SSH to every server in your inventory — nothing needs to be installed on the servers themselves.

Four ideas carry the chapter: (1) the problem is scale — the same task on thousands of heterogeneous servers; (2) Ansible connects agentlessly over SSH (or WinRM for Windows), so a server just needs to be reachable and set up for passwordless login; (3) you list the servers in an inventory file and describe the work in a playbook written in YAML; and (4) for anything complex you organise the playbook into a role, which is just a tidy folder structure for a big playbook.

01
Phase 1 · Theory

What configuration management is, and why Ansible

First the problem configuration management solves, then the tools that solve it, and then the four architectural reasons Ansible became the one everyone reaches for.

T1

What configuration management is, and why it exists

Configuration management is one of the simpler topics in DevOps, and the clearest way to understand it is to watch the problem it grew out of.

Imagine you are a system administrator, back before DevOps existed as a role, and your company runs its own on-premises data centre with a hundred servers — say fifty on one Linux distribution, twenty-five on CentOS, and twenty-five on Ubuntu. Managing your own servers means constantly doing three kinds of work: applying upgrades (when CentOS moves from version 9 to 10, you have to move with it), applying security patches (just as you update your phone the moment a vulnerability is found), and making default installations (perhaps every server should come with Git or a database already installed, to save the developers time).

Now do those three things across a hundred servers with a team of five. Each person gets twenty servers, and they have to log into every one — over SSH for Linux, or a remote protocol for Windows — and run the commands by hand. The old way to cope was to write scripts: a shell script for Linux, a PowerShell script for Windows. But this was fragile for two reasons. First, you had to write in several languages. Second, and worse, the commands differed by distribution — a script written for Ubuntu might not work on CentOS or Alpine — so a script could work on some servers and silently fail on others.

System admin+ fragile scripts Ubuntu · apt CentOS · yum Alpine · apk Windows · PowerShell … × thousands upgradespatchesinstalls
The problem. The same handful of tasks, across many servers running different distributions, each needing slightly different commands — and per-server scripts that break as distributions and commands change.

Then the cloud made it far worse. With the move to the cloud and to microservices, the number of servers went up roughly tenfold while each server got smaller. Where you once had a thousand large servers, you now had ten thousand small ones. The by-hand-and-scripts approach that was already painful became impossible. That pressure created the need for a proper solution — a concept, configuration management, and the tools that implement it. Configuration management aims to solve exactly one thing: managing the configuration of many servers at once, which every organisation of any size now needs.

T2

The tools, and why Ansible won

Configuration management has several well-known tools. Knowing which one to learn — and why — is the practical question.

The popular tools are Puppet, Chef, Ansible, and Salt. Historically, engineers started with Puppet or Chef, which were the first to implement configuration management six or seven years ago. Ansible gained real popularity around 2016 and 2017, and after Red Hat acquired it (around 2018–2019) it has been constantly developed — which is why you often hear it called Red Hat Ansible. Today it is the go-to tool for configuration management.

So the practical advice is simple: if you are confused about where to start, start with Ansible. There is roughly a 90% chance that the organisation you join will be using it. That is not to say nobody uses Puppet, Chef, or Salt — some do — but the majority use Ansible, and it is always better to learn the tool that is most widely used, because that is what gets you into a job. Once you know Ansible well, and if you still have time, you can look at the others.

T3

Why Ansible — the four differences (and the trade-offs)

"When you have Puppet and Ansible, why did you choose Ansible?" is one of the most common interview questions. The answer is four architectural differences, and you should be able to give all four.

Puppet — pull, master–slave Puppet master agent (slave) agent (slave) agent (slave) agents pull config · each needs setup + certs Ansible — push, agentless Control node server (no agent) server (no agent) server (no agent) control pushes over SSH · just an IP in the inventory
The core contrast. Puppet pulls config down to agents you must install and register on each server; Ansible pushes config out from one control node over SSH, with nothing installed on the servers.
  1. Push versus pull. Puppet uses a pull model; Ansible uses a push model. With Ansible, you write your playbook in one place — your laptop or a control node — and push the configuration out to all your servers by running the playbook. You do not wait for each server to pull the config down for itself.
  2. Agentless versus master–slave. This is the big one. Puppet follows a master–slave (master–agent) architecture: you install an agent on every server and register it with the master using tokens and certificates before anything works. Ansible is agentless — there is nothing to install on the servers you manage. You simply list their IP addresses (or DNS names) in an inventory file and set up passwordless SSH authentication, and Ansible can configure them. This matters enormously in a dynamic environment where servers are created and torn down constantly: to manage a new server you just add its IP to the inventory. Ansible can even do this automatically with dynamic inventory, where it auto-detects new servers (for example, any new EC2 instance in a given region) and manages them without you editing the file at all.
  3. Good support for both Windows and Linux. Ansible has strong modules for both operating systems, and especially after Red Hat's involvement its Windows support improved a lot — which is often trickier with Puppet or Chef. Its Linux support is excellent.
  4. Simple YAML instead of a custom language. Puppet makes you learn its own Puppet language. Ansible playbooks are written in plain YAML — a format engineers already know from Kubernetes and elsewhere — so there is no new language to learn.
Be honest about the trade-offs, and know the extensibility story. Ansible is not perfect. Windows configuration is still not as smooth as Linux; its debugging logs are not always easy to read; and it can hit performance limits when running in parallel across very large fleets. On the plus side, Ansible is written in Python, so you can write your own custom modules — for example, to manage your organisation's load balancer — and share them with the community through Ansible Galaxy, from which others can pull and reuse them. Being able to name both the weaknesses and the extensibility is what makes your "why Ansible" answer sound like real experience rather than a memorised list.
02
Phase 2 · Lab

Hands-on — from installing Ansible to writing roles

Install Ansible and wire up the passwordless SSH it depends on, list your servers in an inventory, run ad-hoc commands, write your first playbook, and finally structure a complex playbook into a role. Two small Ubuntu servers are all you need.

L1

Install Ansible and set up passwordless SSH

You need two servers: a control node (where Ansible runs) and at least one target to configure. Create two Ubuntu EC2 instances, and on the control node install Ansible with the package manager — it is the easiest route, and it adds Ansible to your path automatically:

bashsudo apt update
sudo apt install -y ansible        # on Mac: brew install ansible · on Windows: choco install ansible
ansible --version                  # verify it installed (under the hood it uses Python + pip)

The one prerequisite Ansible has is passwordless SSH: the control node must be able to connect to the targets without a password. Set that up by generating a key pair on the control node and copying its public key into the target's authorized keys. The private key never leaves the control node and is never shared:

bash# on the CONTROL node
ssh-keygen                         # creates ~/.ssh/id_rsa (private) and id_rsa.pub (public)
cat ~/.ssh/id_rsa.pub              # copy this public key

# on the TARGET server, paste the control node's public key into:
~/.ssh/authorized_keys             # (ssh-copy-id <target-ip> does this in one step, when it has permission)

# back on the control node — now this connects with no password:
ssh <target-private-ip>

Once ssh <target> connects without asking for a password, the prerequisite is met — for that server and any others you add the public key to. Use the private IP when the servers are in the same VPC. In one line: passwordless SSH is just the control node's public key sitting in the target's authorized_keys.

L2

The inventory file, and ad-hoc commands

The inventory file is where you list the servers Ansible manages. Ansible's default is /etc/ansible/hosts, but it is more convenient to keep your own file next to your playbooks and point Ansible at it. You can also group servers with bracket headers and target a group by name:

text# inventory
172.31.6.228

[webservers]
172.31.62.100

[dbservers]
172.31.62.200

You do not always need a playbook. For a one-off task — "create a file on a hundred servers" — an ad-hoc command is simpler, exactly as you would run a single shell command rather than write a whole script. The form is ansible -i <inventory> <hosts> -m <module> -a "<args>", where -m is the module and -a is its arguments:

bashansible -i inventory all -m shell -a "touch devops-class"   # run on every host in the inventory
ansible -i inventory webservers -m shell -a "nproc"         # run only on the webservers group
ansible -i inventory all -m copy -a "src=./x dest=/tmp/x"   # modules other than shell, e.g. copy

A yellow line means something changed and all is well; a red line means an error. Which module to use, and its arguments, you look up in the Ansible module documentation — there are thousands of modules and nobody memorises them all. The rule of thumb, and a common interview question, is: use an ad-hoc command for one or two tasks, and write a playbook when you have many.

L3

Your first playbook

A playbook is just an Ansible file — the equivalent of a shell script — written in YAML, used when you want to run several tasks. Here is one that installs and starts nginx:

name:what this play does hosts: allwhich servers (from the inventory) become: truerun as root (like sudo) tasks:- name: install nginx → apt: {name: nginx, state: present}- name: start nginx → service: {name: nginx, state: started}
The anatomy. A play has a name, the hosts it targets, an optional become (run as root), and a list of tasks — each task using a module like apt or service.
yaml---
- name: install and start nginx
  hosts: all                       # every server in the inventory
  become: true                     # run as root, like sudo (package installs need it)
  tasks:
    - name: install nginx
      apt:                         # the apt module — equivalent to "shell: apt install nginx", but sturdier
        name: nginx
        state: present             # present = installed
    - name: start nginx
      service:                     # the service module
        name: nginx
        state: started

Run it with ansible-playbook (the ansible command runs ad-hoc commands; ansible-playbook runs playbook files):

bashansible-playbook -i inventory first-playbook.yaml
# the first task is always "Gathering Facts" — Ansible checks the auth and collects info about the target
ansible-playbook -i inventory first-playbook.yaml -vvv   # add -v / -vvv for verbose debug output

Every playbook begins with a Gathering Facts step, where Ansible confirms it can authenticate and collects details about the target, before running your tasks. Two habits worth forming: prefer a purpose-built module (apt, service) over a raw shell command, because the module is more robust if the underlying command changes; and use -vvv when you want to see, step by step, exactly what Ansible is doing on the target — how it establishes the SSH connection, what it gathers, and the result of each task.

L4

Roles — structuring a complex playbook

A two-task playbook fits in one file. A real one does not — and that is what roles are for.

Consider a realistic task: configure a Kubernetes cluster with Ansible, setting one server up as the master and two as workers. (In practice you would create the servers with Terraform — the right tool for provisioning infrastructure — and then configure them with Ansible.) A playbook like that has fifty or sixty tasks, plus variables, certificates, and secrets. Put all of that in one playbook.yaml and it becomes impossible to read. The answer is an Ansible role: an efficient, structured way to write a complex playbook. You create one with ansible-galaxy:

bashansible-galaxy role init kubernetes    # scaffolds a folder of standard directories

That scaffolds a tidy folder structure. Instead of one giant file, each concern lives in its own directory, and a small parent playbook simply names the hosts and points to the role:

kubernetes/ (a role) tasks/ the steps handlers/ react to change templates/ Jinja2 files/ static files vars/ variables defaults/ default vars meta/ info + license tests/ + README.md parent playbook (site.yml): - hosts: all   roles: [ kubernetes ]   # the tasks now live inside the role, not here
The role structure. The tasks, handlers, templates, files, and variables each get their own directory, and the parent playbook just lists the hosts and the role to apply.
  • tasks/ — the actual steps (what used to be the tasks: block in your single playbook).
  • handlers/ — actions triggered by a change, and a place to handle problems (for example, if nginx fails to start, notify someone or roll the change back).
  • templates/Jinja2 templates for config files that need values filled in.
  • files/ — static files to copy to the targets, such as an index.html or a certificate.
  • vars/ and defaults/ — variables, where defaults/ holds the lowest-precedence values that can be overridden.
  • meta/ — metadata and licensing, used when you share the role via Ansible Galaxy; and tests/ plus a README.

The pattern to remember for interviews: you write simple things directly in a playbook, and when a playbook grows complex — many tasks, variables, certificates, secrets — you turn it into a role so it stays structured and readable, and can be shared through Ansible Galaxy.

03
Phase 3 · Interview Q&A

The configuration management & Ansible questions you'll be asked

These are the questions the instructor explicitly flags across Days 14 and 15, with answers built from his explanations. Answer each out loud, then reveal.

Q1What is configuration management, and why is it needed?reveal ▸
Answer

Configuration management is how a DevOps engineer manages the configuration of many servers at once — the upgrades, security patches, and default installations that every server needs. It exists because doing that by hand, or with per-server scripts, does not scale: an organisation has hundreds or thousands of servers, often on different operating systems, and the cloud and microservices pushed those numbers up roughly tenfold. Configuration management lets you describe the desired state once and enforce it across the whole fleet.

Q2Why did you choose Ansible over Puppet or Chef?reveal ▸
Answer

Four reasons. It is push-based — I run a playbook from one control node and it configures everything, rather than each server pulling config down. It is agentless — nothing to install on the managed servers, unlike Puppet's master–slave model with agents, tokens, and certificates; I just list IPs in an inventory and set up passwordless SSH. It has strong support for both Windows and Linux. And playbooks are plain YAML, so there is no custom language to learn as there is with Puppet. It is also the tool roughly 90% of organisations use.

Q3Is Ansible push or pull?reveal ▸
Answer

Ansible is push. You write the playbook on a control node and push the configuration out to all the target servers when you run it. Puppet, by contrast, is pull — the agents pull their configuration down from the master.

Q4What does "agentless" mean, and how does Ansible connect to the servers?reveal ▸
Answer

Agentless means there is nothing to install on the servers you manage — no agent, no registration, no certificates. Ansible connects over SSH (or WinRM for Windows), so a target just needs to be reachable and set up for passwordless login. You list the targets in an inventory file, and Ansible pushes the configuration to them. This is a big advantage in a dynamic environment, because to manage a new server you only have to add its IP to the inventory.

Q5Does Ansible support Windows and Linux? What protocols does it use?reveal ▸
Answer

It supports both. For Linux it connects over SSH, and for Windows it connects over WinRM. Its Linux support is excellent, and its Windows support is good — and improved a lot after Red Hat's involvement — though Windows configuration is still not quite as smooth as Linux.

Q6Does Ansible support all the cloud providers — AWS, Azure, GCP?reveal ▸
Answer

This can sound like a trick, but the answer is simple: Ansible does not care which cloud the server is on. All it needs is that the machine is reachable and that SSH is allowed from the Ansible control node (or WinRM for Windows). So it works the same on AWS, Azure, GCP, or anywhere else — the cloud provider is irrelevant, reachability and SSH access are all that matter.

Q7What language are playbooks written in, and what is Ansible itself written in?reveal ▸
Answer

Playbooks are written in YAML — the same format used across Kubernetes and much of DevOps, which is one of Ansible's advantages. Ansible itself is written in Python, which is why you can write your own custom modules in Python and contribute them back. If asked whether you have written custom modules, be honest — you can say you are comfortable enough with Python to write one whenever it is needed.

Q8What is the difference between an ad-hoc command and a playbook?reveal ▸
Answer

An ad-hoc command is for one or two quick tasks — like running a single shell command instead of writing a script — using the form ansible -i inventory all -m module -a "args". A playbook is for running many tasks together, written as a YAML file and run with ansible-playbook. So the rule is: ad-hoc for one or two tasks, a playbook when there are several.

Q9What is the inventory file, and how do you run tasks on only some servers?reveal ▸
Answer

The inventory file is where all the server names and details are configured — by default at /etc/ansible/hosts, though you usually keep your own file next to your playbooks. To target only some servers, you group them in the inventory with bracket headers, such as [webservers] and [dbservers], and then run against a group by name instead of all. Ansible looks up the group and runs the tasks only on those hosts.

Q10What is dynamic inventory?reveal ▸
Answer

Normally you edit the inventory file to add servers. Dynamic inventory removes even that step: with some configuration, Ansible auto-detects servers — for example, any new EC2 instance created in a given region or availability zone — and manages them automatically, without you touching the file. It is what makes Ansible practical for an autoscaling fleet where servers come and go constantly.

Q11What does become do in a playbook?reveal ▸
Answer

become: true runs the tasks as the root user — the equivalent of putting sudo in front of a command. You need it for anything that requires elevated privileges, such as installing packages with the package manager. You can also use become_user to run as a specific user rather than root.

Q12What is "Gathering Facts"?reveal ▸
Answer

Gathering Facts is the first step of every playbook run. Before your tasks execute, Ansible connects to each target, confirms it can authenticate without a password, and collects details about the server — the operating system, the interfaces, and so on — which your tasks can then use. It runs automatically no matter what playbook you write.

Q13What are Ansible roles, and why use them?reveal ▸
Answer

A role is a structured, efficient way to write a complex playbook. A simple two-task playbook fits in one file, but configuring something like a Kubernetes cluster has fifty or sixty tasks plus variables, certificates, and secrets — which is unreadable in a single file. A role (scaffolded with ansible-galaxy role init) splits all of that into standard directories, so the playbook stays organised and can be shared. The parent playbook then just names the hosts and applies the role.

Q14Explain the directories inside a role.reveal ▸
Answer

tasks/ holds the actual steps; handlers/ holds actions triggered by a change and is where you handle problems; templates/ holds Jinja2 templates for config files; files/ holds static files to copy to the targets; vars/ and defaults/ hold variables (defaults being the lower-precedence, overridable ones); meta/ holds metadata and licensing for sharing via Galaxy; and there is a tests/ directory and a README.

Q15What are handlers?reveal ▸
Answer

Handlers are actions that run in response to a change — a task "notifies" a handler, and the handler runs only if something actually changed. They are also where you handle situations: for example, if a service fails to start, a handler could send a notification or undo the change, so you are not left with a half-configured server. In a role, handlers live in the handlers/ directory.

Q16What are the disadvantages of Ansible?reveal ▸
Answer

Three honest ones. Windows configuration is still not as smooth as Linux. Its debugging is weak — the logs are not always easy to read, even in verbose mode, so tracking down why a playbook failed can be hard. And it can hit performance limits when running in parallel across very large fleets. Being able to name real weaknesses like these makes your answer sound like genuine experience.

04
Phase 4 · Scenario drills

The senior layer — config management on a real fleet

You can now write playbooks and roles. These 10 scenarios are the on-call and interview version: configuration drift, idempotency, secrets, slow runs at scale, partial failures, and knowing when not to configure in place at all. These are authored to match the Scenario Playbook's depth for a domain the course video does not cover. Answer out loud, reveal, and mark yourself.

No scenarios match that search. Clear search
Config Mgmt & Ansible — DevOps Zero → Hero. Theory, Lab & Interview rebuilt from Days 14 & 15 (configuration management, Puppet vs Ansible, and Ansible zero-to-hero); the 10 scenario drills are authored for this chapter, since it has no Scenario Playbook domain. ← All chapters