What Configuration Management Is
Configuration management is the practice of declaring the state a server should be in — its packages, services, files, users, and settings — in version-controlled text, and then having a tool enforce that state on every machine, repeatably. Instead of logging into a box and fixing it by hand, you write down what "correct" means once and let the tool make every server match.
The problem it solves is that hand-configured servers become snowflakes. Two web servers set up months apart by different people drift apart, and nobody can say exactly what is installed on either — so rebuilding one after a disk failure is archaeology against a half-remembered runbook. Declare the configuration as code and those questions have answers: the code is the record, the git history is the changelog, and a second identical server is one run away.
The Snowflake Problem
A server configured by hand carries no memory of how it got that way. Someone installed a package at 2am during an incident, edited nginx.conf to work around a bug, and bumped a kernel parameter — and none of it is written down anywhere except in that one machine's filesystem and one engineer's recollection. The shell history scrolls away, the engineer changes teams, and the knowledge of why the box is the way it is leaves with them.
The sharpest version of this is two machines that are supposed to be identical and are not. web1 and web2 were built a month apart, and a subtle difference — a config flag set on one and not the other — means a request that works on one fails on the other. There is no diff to consult, because nothing ever described what either was meant to be. Each server is unique, and uniqueness is exactly what you do not want from machines that are supposed to be interchangeable.
Convergence to a Declared State
Configuration management inverts the relationship. Rather than you remembering the exact sequence of apt install, systemctl enable, and editing a file, you declare the end state — "nginx is installed, running, and listening on 443" — and the tool figures out how to get there from wherever the machine currently is. It checks reality, computes the gap, and closes it. The declaration is the input; the steps are the tool's problem.
Drift
Once a machine is under management, the declared state becomes the truth and anything else is drift. If someone SSHes in and hand-edits a managed file, the next run notices the difference and puts it back — the local edit loses to the committed declaration. That is the feature, not a bug: it means the answer to "what is the real config of this server?" is always "read the code," and it means a fleet of a hundred machines stays a hundred copies of the same thing instead of a hundred snowflakes quietly diverging.
Provisioning, Configuration, and Orchestration
"Infrastructure as code" is an umbrella over three different layers, and confusing them is the most common newcomer mistake. Provisioning creates the machine — the cloud instance, its disk, its network. Configuration management takes an existing machine and shapes what runs inside it — installs packages, writes config files, manages services and users. Orchestration coordinates work across many machines in order — deploy to these, wait, then those.
Ansible lives in the configuration-management layer, and reaches into orchestration. It does not, by design, create your servers from nothing the way a provisioning tool does — that is a different job for a different tool. Keeping the layers distinct, rather than forcing one tool to do all three, is what keeps an automation pipeline clean. The next two topics place Ansible precisely: first against other configuration-management tools, then against the provisioning tool it is most often confused with.
Idempotency
Idempotency means applying the same configuration twice yields the same result — the first run installs what is missing and the second changes nothing, because nothing needs changing. The tool checks current state before it acts, so a run is a reconciliation, not a blind replay of commands. This is the property that makes it safe to run the same configuration every hour, in a pipeline, or after an incident, without wondering whether the second run will break what the first one fixed.
A one-shot setup script does not have this property. Run it twice and the second run either fails because the user already exists, or silently does the wrong thing because it assumed a clean machine. The difference between a setup script and configuration management is exactly idempotency — the tool asks "is this already true?" before every action, and a script does not.
Provisioning — tools like Terraform and CloudFormation create servers, networks, and load balancers from nothing and track them so they can be destroyed. Reach for it to bring infrastructure into existence and manage its lifecycle.
Configuration management — tools like Ansible and Puppet take an existing machine and shape what runs inside it. Reach for it to install software and manage config. They are layers, not rivals: provisioning builds the VM, configuration management sets it up, and most real stacks use both.
- Configuring a production server by hand "just this once" and meaning to codify it later — the codification never happens, and the box becomes an undocumented snowflake nobody dares touch or rebuild.
- Treating a wiki page or runbook as the source of truth while engineers SSH in and edit files directly — the doc lies within a week, and the next automated run reverts a hand-made fix nobody captured.
- Expecting a provisioning tool to install packages and tune the OS — standing up a cloud instance is not configuring it, and bolting configuration onto the provisioning step produces brittle, unrepeatable machines.
- Writing a one-shot Bash setup script and calling it configuration management — it fails or double-applies on the second run because it has no idea what is already done.
- Leaving some servers under management and patching others by hand, so the fleet splits into "machines the code describes" and "machines only one person understands" — the second set is where outages hide.
- Bring a server under configuration management from day one, before it reaches production, so there is never a hand-built baseline to reverse-engineer.
- Make every change through the tool and never by hand on a managed file, so the declared state and the real state never disagree.
- Keep all configuration in git with the same pull-request review as application code, so every package and setting has a reviewed, revertible history.
- Separate provisioning from configuration deliberately — let one tool create the machine and another configure it — rather than forcing either across the boundary.
- Run the configuration regularly, not just at build time, so drift is corrected continuously instead of discovered during an incident.
Knowledge Check
Why does a hand-configured server become a liability over time?
- Its configuration lives only in its filesystem and one person's memory, so it cannot be reviewed or reliably rebuilt
- The physical disks and CPU on a machine set up by hand wear out measurably faster than on an automated one
- The operating system eventually starts refusing to apply security updates to any server that was edited by hand
- Manual configuration always ends up consuming far more disk space over time than the same setup applied automatically
What does it mean for a configuration to be idempotent?
- Applying it a second time changes nothing, because the tool checks current state before acting
- It can only ever be applied one single time and then permanently locks itself into a read-only mode
- It tears down and then recreates every managed resource completely from scratch on each separate run
- It must always be run at least twice in a row before any change actually takes effect
A server is under configuration management and an engineer SSHes in to hand-edit a managed config file. What happens on the next run?
- The tool detects the difference from the declared state and reverts the file to match the code
- The tool reads the manual edit on the host and adopts it as the new desired state for every run going forward
- The run halts on that one host and refuses to continue any further until a human reviews the edit
- Nothing happens, because the tool only manages installed packages and never touches files
Which task belongs to configuration management rather than to the provisioning layer?
- Installing nginx and writing its config file on an existing server
- Creating the cloud instance and attaching its disk and network
- Allocating a managed database instance from nothing on the cloud provider
- Standing up a load balancer and reserving its public IP from scratch
You got correct