Terraform Plan, State, Modules, and Physical Effects
Follow Terraform from reviewed configuration through state and AWS APIs to real compute, memory, storage, and network effects.
System map · Day 19
Whole-system design
Five stable layers. Today's work is expanded and linked; the rest stays in context.
Product and authority
Covered — People and product entry points · Identity and policy · HelixWorks control plane · Generated application plane
Delivery and desired state
Covered — Git desired state · CI and immutable artifacts · Argo CD reconciliation
Cloud and orchestration
Covered — Kubernetes or EKS control plane
Terraform and AWS APIs
Source-backed today
Turns reviewed modules and variables into a scoped provider plan before any AWS mutation occurs.
Accounts, VPC, DNS, and private paths
Source-backed today
Materializes module choices as VPCs, subnets, routes, interfaces, and addresses in AWS.
Compute and traffic
Covered — Platform service workloads · Generated app workloadsAhead — Ambient mesh data plane
Worker compute
Source-backed today
Materializes capacity choices as EKS-managed EC2 worker CPU and memory.
Storage and evidence
Covered — Cluster desired and live state · Product data and artifacts · Evidence and observability
Infrastructure state
Source-backed today
Binds Terraform addresses to real AWS identities so future plans compare the correct resources.
The enterprise problem and today’s slice
Enterprise problem: A small Terraform edit—Terraform is a stateful Infrastructure as Code (IaC) engine—can replace an Elastic Kubernetes Service (EKS) node group, expose a secret through state, race another operator, or leave paid AWS resources partly changed while HelixWorks remains unavailable. Whole-course context: The incoming evidence assigns one owner to infrastructure, cluster lifecycle, Kubernetes workloads, and GitOps; today examines Terraform as the IaC implementation for the infrastructure boundary. Today’s slice: We connect HashiCorp Configuration Language (HCL), modules, plan, approval, locked remote state, providers, AWS APIs, physical effects, drift, import, and guarded state repair. End-of-day evidence: A dev run binds commit, fresh plan, policy, approval, state version, execution identity, AWS resource IDs, cluster observation, customer probe, denied unsafe change, environment, timestamp, run, and trace IDs. Still unsolved: Separate AWS account foundations and production Identity and Access Management (IAM) guardrails remain deferred.
Customer outcome and implementation focus
The customer outcome is a reviewable terraform plan, state, modules, and physical effects change, not a collection of requirements. This day starts with the implementation boundary, then uses the command or manifest below to produce positive, denied, and recovery evidence.
Components in focus
Terraform CLI/modules, remote-state backend, and AWS provider APIs; VPC, EKS, nodes, disks, and network hardware; versioned state object storage/lock table; cache: not involved.
This map names the implementation boundary for this day. The service or controller changes only the state it owns; runtime and audit evidence let the operator distinguish a declared change from an effective one.
Trace Terraform declarations into physical resources
Trace HCL to physical reality
Changing a node-group shape is not merely editing text: the provider may replace virtual machines, drain pods, allocate memory, and move network traffic. Review the plan for these effects before execution.
module "environment" {
source = "../../modules/environment"
environment = "dev"
expected_account_id = var.account_id
deployer_role_arn = var.deployer_role_arn
monthly_budget_usd = 250
region = var.region
vpc_cidr = "10.10.0.0/16"
kubernetes_version = var.kubernetes_version
node_instance_types = ["m7i.large"]
node_min_size = 2
node_max_size = 5
deletion_protection = false
}
Repair state only after proving reality
terraform state rm does not delete AWS infrastructure; it only removes Terraform’s mapping and can therefore orphan a live resource. Inspect exact identity first, back up versioned state, and prefer import when the resource exists.
: "${AWS_PROFILE:?set the approved AWS profile}" "${AWS_REGION:?set the intended AWS region}" "${EXPECTED_ACCOUNT_ID:?set the intended 12-digit AWS account}"
actual_account="$(aws --profile "$AWS_PROFILE" --region "$AWS_REGION" sts get-caller-identity --query Account --output text)"
[ "$actual_account" = "$EXPECTED_ACCOUNT_ID" ] || { echo "AWS account mismatch" >&2; exit 1; }
terraform -chdir=infra/stacks/dev state show 'module.environment.aws_eks_cluster.this'
aws --profile "$AWS_PROFILE" --region "$AWS_REGION" eks describe-cluster --name helixworks-forge-dev --region eu-west-2
terraform -chdir=infra/stacks/dev plan -out=verified.tfplan
Do not run a removal command from this lesson. The guarded decision is: if AWS returns the exact expected resource, refresh or import; if independent account-and-region inventory proves it absent, use the approved repair workflow, then re-plan and verify the recreated or adopted identity.
Key takeaways
Terraform connects configuration to physical resources through a reviewed plan, state mapping, provider, and observable AWS effects.
- State is sensitive durable mapping, not the infrastructure itself.
- Modules reuse design while separate roots preserve environment isolation.
- State surgery is last-resort record repair after exact independent inspection.
Checklist
An apply is complete only when its real effects and customer outcome are known.
- [ ] Plan is fresh, saved, policy-checked, and approved by checksum
- [ ] Backend is encrypted, locked, versioned, and environment-scoped
- [ ] Review names replacement, capacity, cost, and availability effects
- [ ] AWS, Kubernetes, customer, negative, and unaffected evidence are recorded