Terraform 004 quick-recall
Terraform 004 flashcards
Flip through 10 cards — one per Terraform 004 topic — and self-test the key exam facts. Free, no account needed. These exams reward fast recognition, which is exactly what flashcards train.
1 / 10
Every Terraform 004 flashcard, by exam domain
90 key facts across 8 domains — the full deck below, so you can scan it even without the interactive cards.
Infrastructure as Code (IaC) with Terraform
8% of the exam- IaC defines infrastructure in machine-readable, version-controlled files — the definition files are the source of truth, not the console
- The advantages of IaC patterns: versioning, repeatability, automation, reduced human error, and self-service
- Approvals live in pull requests; state holds current resource metadata and the provider audit log records API calls — neither records who approved a change
- Configuration rebuilds infrastructure, not the data inside it — databases still need backups
- Terraform is declarative: it converges on the declared state — re-applying unchanged code does nothing, removing a block or lowering count plans destroys, and a manually deleted resource is planned as a create
- In plan output, ~ is an in-place update while -/+ and +/- are replacements that produce a new object — the line to catch for stateful resources
- Providers are separately versioned plugins installed only by terraform init; Terraform core makes no API calls, and one binary serves every platform
- One configuration, plan and state can span clouds, on-premises (vSphere, agentless) and SaaS APIs, with cross-provider references — but resource types are provider-specific and do not port between clouds
- Only provider resources are managed; provisioners and data sources are not. Existing resources are adopted by writing resource blocks and importing them
- Terraform provisions infrastructure lifecycle (immutable, replace-on-change, e.g. a new image); Ansible, Chef, and Puppet manage software on existing servers — complementary, not competing
Terraform fundamentals
11% of the exam- Providers are plugins that map resource types to platform API calls; Terraform core makes no cloud API calls itself
- required_providers (inside the terraform block) declares each provider's source and version; an undeclared provider is assumed to be hashicorp/<name>, so non-HashiCorp providers must be declared
- required_version constrains the Terraform CLI and stops init/plan when unmet; Terraform never installs its own binary. A version argument in a provider block is deprecated
- terraform init installs providers into .terraform/providers; a plugin cache reuses downloads across directories, while -plugin-dir installs only from that directory
- ~> 5.1 allows 5.x from 5.1 upward but never 6.0; ~> 5.1.0 allows only 5.1.x. Pre-releases match only an exact constraint
- One version per provider serves the root and every module, so all constraints must overlap; reusable modules set a minimum (>=), root modules bound upgrades
- Commit .terraform.lock.hcl; init keeps locked versions, -upgrade re-selects, -lockfile=readonly guards CI, and providers lock -platform adds checksums for other platforms
- alias adds configurations of one provider, selected with provider = aws.west; two different providers with the same type need distinct local names
- State maps configuration to real objects, stores dependency metadata and caches attributes; it holds secrets in plain text, and sensitive = true only redacts CLI output
Core Terraform workflow
19% of the exam- The core workflow is Write, Plan, Apply — plan previews changes as a diff, apply executes them, and the loop repeats for every change.
- terraform init must run first in any new or cloned directory, and again when providers, modules (source or version) or the backend change — not when a provider argument like region or a resource argument changes. It creates no infrastructure and, with the local backend, no state file.
- terraform get installs modules only; terraform providers lock updates the lock file without installing plugins. Neither replaces init.
- .terraform.lock.hcl pins provider versions and checksums and is committed; .terraform is not. Plain init reinstalls the locked version; init -upgrade picks the newest version within the constraints (never past them), upgrades modules too, and rewrites the lock file to commit.
- Modules are not in the lock file. For registry modules, only an exact version ("3.1.0") installs identical module code on every run; Git sources pin with ?ref= set to a tag or commit.
- A backend change needs -migrate-state (copy state; add -force-copy to skip prompts, which still overwrites the destination) or -reconfigure (new backend already holds the right state). -backend-config supplies partial configuration and is accepted by init only.
- terraform validate checks syntax and internal consistency offline after init (use init -backend=false in CI); fmt -check checks only formatting; plan -refresh=false still needs providers and state.
- terraform plan is read-only and holds the state lock; -refresh=false skips drift detection, -refresh-only reconciles state, -destroy previews a teardown. A plain plan exits 0 even with changes; -detailed-exitcode returns 2 when changes are pending.
- Plan symbols: + create, ~ update in-place, - destroy, -/+ replace destroy-first, +/- replace create-first (create_before_destroy), <= read; a replacement counts as one add plus one destroy.
- terraform plan -out=tfplan saves a binary, possibly sensitive plan; terraform apply tfplan executes exactly it without a prompt, with variables embedded, and rejects it if the state has changed since.
- terraform apply is the only core-workflow command that changes infrastructure: it plans, waits for the literal word yes, executes in dependency order, and records results in state while holding the state lock. An empty plan finishes without a prompt.
- Apply skips the approval prompt in exactly two cases: -auto-approve, or applying a saved plan file. -input=false (or TF_INPUT=0) disables prompts, so a bare apply fails; TF_IN_AUTOMATION only adjusts output.
- A saved plan embeds the actions, a configuration snapshot and variable values: later .tf/.tfvars edits do not affect it, extra planning options are rejected, and it is refused as stale if state changed since it was created.
- Apply is not transactional: completed operations stay in state and you re-run apply after fixing the cause. A failed creation-time provisioner leaves the resource tainted, so the next plan replaces it.
- Up to 10 operations run concurrently by default; -parallelism=n changes the ceiling for plan, apply or destroy but never overrides dependencies. -lock-timeout only governs retrying the state lock.
- terraform destroy (= terraform apply -destroy) deletes everything in the selected workspace's state, including child-module resources, in reverse dependency order; data-source objects, unmanaged resources, the configuration and the state file remain.
- prevent_destroy = true makes any destroying plan error (a full destroy deletes nothing), but it protects only while the block is in configuration.
- -target is exceptional-use; a targeted destroy also removes the target's dependents. terraform fmt rewrites in place (current directory unless -recursive or a path is given); -check exits non-zero, -write=false exits 0, -diff alone still writes, and fmt never validates or reorders.
- Pipeline order: fmt -check, init, validate, plan -out, then apply the saved plan.
Terraform configuration
22% of the exam- resource blocks create and manage infrastructure; data blocks only read existing infrastructure and never change it.
- Resources are referenced as type.name (aws_instance.web); data sources take the data. prefix (data.aws_ami.ubuntu).
- Data sources are read during plan, unless an argument is unknown until apply or they depend on a resource with pending changes; then the read is deferred to apply.
- Deleting a resource block plans a destroy (its prevent_destroy goes with it); a removed block with destroy = false, or terraform state rm, stops management without destroying.
- Referencing another resource's attribute, such as aws_subnet.app.id, creates an implicit dependency that orders operations automatically.
- A variable without a default is required: Terraform prompts, or errors when -input=false or no terminal is available. nullable defaults to true, so an explicit null overrides the default unless nullable = false.
- Precedence, lowest to highest: TF_VAR_, terraform.tfvars, terraform.tfvars.json, *.auto.tfvars (lexical), then -var and -var-file together in command-line order, last wins.
- An output derived from a sensitive value must declare sensitive = true itself; terraform output NAME, -raw and -json still print it in plain text.
- Collections (list, set, map) have one element type, so list(any) unifies mixed elements; tuples and objects keep per-position or per-attribute types, and object conversion drops undeclared attributes.
- The conditional is condition ? true_val : false_val; null means "argument not set", so cond ? value : null makes an argument optional, but count needs a number (cond ? 1 : 0).
- Splat (resource[*].attribute) works on count-created lists; for_each-created resources form a map, so use values() or a for expression.
- You cannot write custom functions in Terraform; know merge (later wins), contains(list, value), element (wraps), flatten, toset, jsonencode/jsondecode, format vs templatefile, and cidrsubnet arithmetic.
- Indexing a missing map key errors; lookup and try fall back on absence/errors, can tests for errors, and coalesce skips null and empty strings. try does not replace a null value.
- count takes a number and reindexes when a middle item is removed (shifted indexes change, the last is destroyed); for_each takes a map or set of strings and keeps stable keys that must be known at plan time.
- depends_on takes whole resource, data source or module references only, adds to implicit dependencies, and on a data source defers the read to apply when its dependency changes.
- validation, precondition and postcondition fail the run (postconditions can read self; nothing is rolled back); top-level check blocks run at the end of plan/apply and only warn.
- sensitive redacts output only; state keeps sensitive values in plaintext. Vault dynamic secrets expire and are revoked; ephemeral resources and write-only arguments (bump the _wo_version to rotate) keep secrets out of state.
Terraform modules
11% of the exam- A module is a container for multiple resources used together; the directory where you run Terraform is the root module, and anything called via a module block is a child module.
- The source argument is required and must be known at init: a literal string on Terraform 1.12 (1.15+ also allows locals and const variables, never ordinary variables or resource attributes). To pick a module per environment, use separate module blocks gated by count.
- Local paths start with ./ or ../ and load in place; absolute paths are copied into .terraform/modules and need another init after edits.
- github.com/ORG/REPO clones over HTTPS, git@github.com:ORG/REPO.git over SSH; an https URL without git:: is an HTTP source. Only a commit SHA in ?ref= is an immutable Git pin.
- Module variables are not global: values enter a child only through declared inputs passed in the module block — at every level of a nested tree — and leave only through declared outputs read as module.NAME.OUTPUT (module.NAME[*].OUTPUT for all count instances).
- Module blocks support count, for_each, depends_on and providers. A child with its own provider blocks cannot be used with count, for_each or depends_on, and module depends_on defers data reads to apply whenever the depended-on objects have pending changes — prefer passing an attribute as an input.
- The version argument works only for registry modules; ~> lets only the rightmost component rise, prereleases match only an exact constraint, and the lock file does not record module versions.
- terraform init installs modules into .terraform/modules; terraform get downloads modules only; only -upgrade (or get -update) moves an installed module to a newer acceptable version.
Terraform state management
11% of the exam- The local backend is the default: state lives in terraform.tfstate in the working directory (previous version in terraform.tfstate.backup), not in .terraform/ - and a fresh clone without the uncommitted state file has no state at all.
- plan, apply, destroy, import and state-writing commands take the lock automatically; terraform_remote_state reads do not.
- -lock-timeout defaults to 0s (fail at once) and only controls waiting; -lock=false skips locking for that one command without releasing anyone else's lock.
- force-unlock LOCK_ID releases an orphaned lock after a confirmation prompt (-force skips it), checks nothing and repairs nothing; another process cannot unlock local state.
- s3 locks only with use_lockfile = true (default false) via a <key>.tflock object; dynamodb_table is deprecated and may coexist with use_lockfile while migrating. gcs locks natively; azurerm uses a blob lease.
- Backend arguments must be literals or come from terraform init -backend-config: var., local., terraform.workspace, TF_VAR_ and tfvars cannot feed a backend, and later -backend-config options win.
- -backend-config values are stored in plain text in .terraform/ and plan files; keep credentials in environment variables or credential files, and protect state with access control and encryption, since sensitive = true only redacts output.
- Changing backends: init -migrate-state copies state, -force-copy does so without prompts, -reconfigure copies nothing.
- terraform_remote_state exposes only root module outputs yet needs read access to the whole state; publish values to a separate store or use tfe_outputs for least privilege.
- A normal plan refreshes in memory: changed updatable attributes become in-place updates, deleted objects are planned for creation. -refresh-only accepts drift into state only; -refresh=false skips refresh and misses unrefreshed drift.
- State surgery: terraform taint is deprecated in favour of plan/apply -replace=ADDRESS, and terraform state rm makes Terraform forget a resource without destroying the real object.
Maintain infrastructure with Terraform
8% of the exam- terraform import ADDRESS ID writes state immediately and only state; ADDRESS must be a managed resource block that already exists, and ID is the provider-specific identifier its docs define - it never generates or edits .tf files.
- Import into count/for_each instances with addresses like aws_iam_role.svc["ci"] (single-quoted in a POSIX shell); the provider configuration used by the CLI import cannot depend on data sources or other resources.
- Import blocks are plannable, apply the import at terraform apply, support for_each bulk import from Terraform 1.7 (to = res[each.key], id = each.value) and are idempotent - a leftover block plans nothing.
- terraform plan -generate-config-out=FILE writes HCL only for import targets without a resource block; the file must not exist, and generated mutually exclusive arguments must be pruned before planning again.
- state list = addresses (-id= for reverse lookup); state show ADDRESS = one resource's attributes; show FILE = whole state or a saved plan; state pull = the raw state file; output = root outputs.
- terraform show -json is the documented integration format for tools; terraform plan -json runs a new plan rather than reading a saved one.
- terraform output -raw prints a bare primitive for scripts; sensitive outputs are redacted only in the all-outputs listing and print in plain text when named or with -json/-raw.
- TF_LOG turns on logging to stderr (TRACE, DEBUG, INFO, WARN, ERROR, or JSON); TF_LOG_PATH chooses a file but enables nothing; TF_LOG_PROVIDER overrides TF_LOG for providers, while TF_LOG_CORE applies only when TF_LOG is unset. Verbose logs can hold sensitive data - redact before sharing.
HCP Terraform
10% of the exam- HCP Terraform (formerly Terraform Cloud) is HashiCorp's managed platform: remote runs, versioned remote state with automatic locking, stored variables, and team governance; Terraform Enterprise is the self-hosted version.
- Integration: authenticate (terraform login interactively, TF_TOKEN_app_terraform_io in CI — never a token in the cloud block), add a cloud block (organization + workspace name or tags), then terraform init, which is required before plan or apply and can migrate local state.
- Run workflows: CLI-driven, VCS-driven (merges run plan-and-apply, pull requests get speculative plans) and API-driven (upload a configuration version, no Terraform binary or VCS needed). CLI apply is refused on VCS-connected workspaces; saved plans (plan -out, apply FILE) apply exactly the reviewed plan.
- Execution modes: remote (default), local (runs on your machine; the workspace only stores state and does not supply its variables) and agent (self-hosted agents inside private networks, outbound connections only).
- An HCP Terraform workspace owns state, variables, run history and permissions — a CLI workspace is only an alternate state file. Projects group workspaces so team access, variable sets and policy sets apply to all of them; project roles are Read, Write, Maintain and Admin.
- Credentials go in environment variables; sensitive makes a value write-only for people but still passes it to runs and does not scrub it from output or state. Precedence: priority variable sets > CLI -var > workspace variables > project sets > global sets > tfvars files.
- Workspaces share outputs via remote state sharing (governs terraform_remote_state, which needs the full snapshot) or tfe_outputs (outputs only, governed by its token). Run triggers queue a downstream run after a source apply; they auto-apply only with the separate Auto-apply run triggers setting.
- Policy sets hold Sentinel or OPA policies (one framework per set), scoped globally (with exclusions), to projects or to workspaces. Sentinel: advisory, soft mandatory (overridable), hard mandatory. OPA: advisory, mandatory (overridable with Manage Policy Overrides). Run tasks run at pre-plan, post-plan, pre-apply or post-apply as advisory or mandatory; cost estimation shows monthly cost and delta before apply.
Keep studying Terraform 004
Terraform 004 flashcards: your questions
Source
Exam structure, domain weights and scoring on this page come from the official Terraform 004 exam guide.
- HashiCorp Terraform Associate certification page — HashiCorp