HFCP study materials
HFCP study resources

HFCP: Infrastructure as Code with Terraform

HFCP · Work through your exam, one topic at a time.

All guide sections

Infrastructure as Code with Terraform

Domain 2 - Infrastructure as Code with Terraform. This domain tests the Terraform workflow and the mechanics behind it: HCL configuration, providers, state, plan/apply, modules, meta-arguments, and drift. Questions often hinge on why a plan proposes replacement or why state must be shared.

Core rules

  • Terraform is declarative: you describe resources; Terraform builds a dependency graph and computes a diff against state and refreshed remote objects.
  • State maps configuration addresses to real object IDs and stores attributes. It can contain sensitive values, so use a remote backend with encryption, access control, and locking.
  • terraform init installs providers and modules; plan refreshes and previews; apply executes the planned changes.
  • Modules package reusable configuration; variables are inputs, outputs are returns, and version constraints pin provider and module behavior.
  • count indexes instances by position; for_each keys them by map or set member. Keyed instances survive unrelated list edits; indexed instances can be recreated when an earlier element is removed.
  • lifecycle controls create_before_destroy, prevent_destroy, and ignore_changes; use these deliberately, not to hide drift.

Worked example

You have variable 'buckets' { default = ['logs','data','backup'] } and a resource using count = length(var.buckets) with bucket = var.buckets[count.index]. Removing 'data' shifts 'backup' from index 2 to index 1. Terraform plans to update the bucket name on index 1 and destroy index 2 - potentially destructive. Rewriting as for_each = toset(var.buckets) and bucket = each.key gives each bucket a stable address such as aws_s3_bucket.this['backup'], so removing one key only affects that key. The reasoning: Terraform addresses instances by count index or by key, and identity determines whether a change is an in-place update or replacement.

Traps

  • Committing terraform.tfstate or plan files with secrets.
  • Expecting plan to catch manual console changes without refresh; drift detection depends on refresh or separate tooling.
  • Using -target as a routine deployment method; it leaves the rest of the graph unverified.
  • Confusing CLI workspaces (state partitions in one configuration) with HCP Terraform workspaces (separate configuration, variables, and state).
  • Forgetting that changing a resource's immutable attribute forces replacement, not an in-place update.