Project challenges / verified progress
Beacon: build the ground it stands on

The engineering notebook

Configure after provisioning

What belongs in Ansible instead of Terraform?

Loading statusStage 8 of 9

  • Workspace not ready
  • Agent not ready
Focus25:00
A small focus ritual

0 focus sessions completed. Every fourth session offers a longer break. Start each phase when you are ready.

Study time never unlocks verified lesson progress.

Loading...

Loading verified progress...

Loading GitHub account...
Phase 4 — Configure and leave no bill

Step 01 of 06

Learn the concept

Terraform can run shell commands. That does not mean it should become a remote shell with a state file. Provisioning decides what exists; configuration management brings machines to a known software state after they exist.

PROVISION, INVENTORY, CONFIGURE01Terraformcreates host and outputs02Inventorynames reachable hosts03Playbookidempotent tasks04Beacon readyruntime prerequisitesno drift shell
Terraform and Ansible overlap at the boundary, which is where teams make a mess. A clean handoff is simple: Terraform outputs where the host is; Ansible configures what runs on it.
Step 01

The ideas this is made of

Provisioning and configuration have different clocks

A subnet may live for years. A package version may change next week. Terraform's state model is good for durable infrastructure objects with provider IDs. It is awkward for line-by-line operating system configuration. Ansible can run repeatedly against existing hosts, install packages, write files and restart services without pretending every command is a cloud resource.

Inventories make targets explicit

An Ansible inventory maps names and groups to connection details. For Beacon, Terraform can output the host DNS name, and the inventory can put it in a beacon group. That separates discovery from configuration. Hard-coding a public IP inside a playbook works once and then fails as soon as the instance is replaced.

Modules are safer than shell

Ansible modules such as apt, dnf, copy, template and service know how to check current state before changing it. A raw shell command usually does not. shell: apt install docker may report changed every run or fail differently across distributions. Use shell when no module exists, and add creates, removes or changed_when so idempotence is explicit.

Roles keep bootstrap work reusable

A role packages tasks, handlers, templates and defaults under a named directory. That matters once the bootstrap grows from installing Docker to writing systemd units, users and log settings. Roles also make review easier: platform bootstrap can change without burying every task in one playbook. Like Terraform modules, roles should hide decisions rather than expose every variable.

An idempotent package task
---
- name: Prepare one Beacon host
  hosts: beacon
  become: true
  tasks:
    - name: Install Docker
      ansible.builtin.package:
        name: docker
        state: present

The module checks package state. Running the playbook twice should not reinstall Docker or report a change when the package is already present.

Terraform or Ansible

WorkBetter toolReason

Create VPC

Terraform

Provider object with ID

Install Docker

Ansible

Host configuration

Open port 22

Terraform

Cloud firewall rule

Write config file

Ansible

File content on host

Create IAM role

Terraform

Cloud identity object

What these are called on the job

  • Inventory — The list of hosts and groups Ansible can target, plus connection variables.

  • Playbook — A YAML file containing ordered plays and tasks for one or more host groups.

  • Role — A reusable Ansible package containing tasks, handlers, templates and defaults.

  • Check mode — Ansible's dry-run mode, requested with --check, for modules that can predict changes.