Ansible is the second major IaC tool in this course. Where Terraform declares the desired state of cloud infrastructure (what AWS resources should exist), Ansible declares the desired state of what runs *on* that infrastructure (what packages are installed, what configuration files contain, what services are running). Terraform provisions the server; Ansible configures it. Together, they implement the complete provision-then-configure pattern: Terraform creates the EC2 instances, RDS databases, and load balancers, and Ansible installs Nginx, configures PostgreSQL clients, deploys application code, and sets operating system hardening policies. This two-tool architecture separates infrastructure concerns from configuration concerns, enabling each tool to be used where it excels rather than overloading one tool to do both.
Ansible's inventory is the foundation of everything — it is the list of hosts that Ansible manages, organised into groups, with variables that apply at the host or group level. A misconfigured inventory means Ansible runs against the wrong hosts, applies the wrong configuration, or skips critical servers. Understanding inventory — both static (defined in files) and dynamic (queried from cloud APIs at runtime) — is the prerequisite for every other Ansible concept. The inventory is also where the provision-configure handoff happens: Terraform creates EC2 instances and tags them with Name and Role tags; the Ansible dynamic EC2 inventory plugin queries the AWS API for those tagged instances and makes them available as Ansible hosts, automatically. This tag-based discovery means new instances automatically appear in the Ansible inventory as soon as they are tagged by Terraform — no manual inventory updates required.