Ansible
Post-provision configuration and hardening for managed hosts, split across 28 roles and applied in a deliberate order that preserves management access.
What it is & why I use it
Ansible is the configuration-management layer of AutomationLab. Terraform brings a VM into existence; Ansible turns that bare VM into a configured, hardened, monitored host. It runs as the configure stage of the provisioning pipeline, after the machine exists and before it is handed over as ready.
I use it because configuration should be declarative and idempotent: the same play run twice leaves the host in the same state, so "converge the host to what the role says" replaces a pile of one-off setup commands nobody can reproduce.
How I use it in the lab
- Roles, not scripts. Each concern is a role with documented defaults - a firewall role, a time-sync role, a monitoring-agent role - composed into a single host-configuration play.
- Runs from the pipeline, as an unprivileged user. The configure stage runs Ansible from the CI agent under a dedicated automation user, not root, with the collection path pinned so runs are reproducible regardless of which agent picks up the job.
- Secrets pulled at runtime. Anything sensitive a role needs comes from the secrets manager during the run - nothing sensitive is stored in inventory or vars in the repo.
- Deliberate role order. The play applies firewall, then time-sync, then the monitoring agent - and that order is load-bearing, not cosmetic (see the gotcha).
Architecture
Lessons learned & gotchas
- Idempotence is a feature you have to test. A role is only trustworthy once a second run reports zero changes. A task that keeps reporting "changed" is usually lying about convergence and will fight you later.
- Pin the collection path. If roles depend on collections, the path they load from must be fixed and owned by the run user - not left to whatever happens to be installed on a given agent - or the same play behaves differently on different runners.
- Run as a real service account, not root. Least privilege applies to configuration management too; a role that needs elevation should ask for it explicitly, so "what can this play change?" stays answerable.
Impact
Ansible is what makes "provisioned" mean "configured and hardened" through a repeatable path. The firewall-ordering lesson is the one I keep closest: automation that can lock itself out of the very host it is configuring is a trap, and the defense is encoding the safe order into the roles to reduce the chance of an ordering mistake.