How to pass HashiCorp Certified: Terraform Associate (TF-Associate-004)
24 min read8 domains coveredFree practice, no sign-up
The HashiCorp Certified: Terraform Associate (004) is an associate exam that proves day-to-day fluency with Terraform. It tests whether you understand infrastructure as code and can drive the core write, plan, apply workflow, author configuration, compose modules, manage state, maintain running infrastructure, and use HCP Terraform. Version 004 is the current exam and it tracks a recent Terraform release, so material written for 002 or 003 is the main thing that will trip you up.
It suits practitioners who already touch Terraform: cloud and platform engineers, DevOps and SRE staff, and developers who provision their own infrastructure. If you have run init, plan and apply against a real provider and edited a state backend, much of the exam will feel like naming what you already do. If Terraform is new to you, the gap is closable in a few focused weeks because the exam rewards understanding the workflow over memorising every function.
The questions are mostly short and practical: what a command does, what a plan will show, which construct fits a stated need. Many wrong options are true statements about Terraform that simply do not answer the scenario, so the skill being tested is picking the right tool for the situation, not reciting a definition. Practise on scenario questions that explain every option, so you learn why each distractor fails rather than only which letter is correct.
Terraform Associate 004 rewards knowing what each command and construct actually does in the write, plan, apply workflow, not memorising every function.
Difficulty
Intermediate
Best for
Cloud, platform, DevOps and SRE engineers, and developers who provision their own infrastructure, who want a recognised credential proving hands-on Terraform fluency.
Prerequisites
None required. Hands-on time running init, plan and apply against a real provider makes the material far quicker to absorb.
Not published by HashiCorp
Questions
60 min
Time allowed
$70.5
Exam cost (USD)
294
Practice questions
How this exam thinks
Three habits separate a comfortable pass from a near miss on Terraform Associate 004, and the first is simply being on the right version.
First, answer as 004, not as 002 or 003. HCP Terraform is the current product name, so treat Terraform Cloud as an old label the distractors use. Prefer -replace over the deprecated taint command for forcing a resource to be recreated. Reach for the import block, not only the terraform import command, when a scenario describes bringing existing infrastructure under management as code. Most third-party practice material and a lot of general knowledge is a version or two behind, so when two options look right, the more current one is usually what the exam wants.
Second, the exam is precise about which command does what, and especially about which step changes infrastructure. Only apply and destroy change real resources. init installs providers, downloads modules and sets up the backend, and creates nothing. validate checks syntax and consistency with no provider access. plan previews and writes nothing. fmt only rewrites style. A large share of questions are won by refusing to let a plausible-sounding option blur those boundaries.
Third, know the rules that have one correct answer. Variable precedence is fixed: a command-line -var or -var-file beats a TF_VAR_ environment variable, which beats terraform.tfvars and auto.tfvars files, which beat a variable's default. State stores secrets in plaintext even when a value is marked sensitive, so sensitive hides output but does not protect state. A data source reads, a resource manages. Implicit dependencies come from references and are preferred; depends_on is for an ordering the configuration cannot express. When a question turns on one of these, there is a right answer and the rest are traps, so make them automatic.
What each domain tests and how to study it
The TF-Associate-004 blueprint is split across 8 domains. Weights are the official share of the exam; see the official exam guide for the authoritative breakdown.
What you must be able to do. Explain what infrastructure as code is, map an organisational problem to the IaC advantage that solves it, and say why one Terraform workflow spans many providers.
In one sentenceThe why behind Terraform: declarative desired-state configuration under version control, the advantages that follow, and one workflow across multi-cloud and hybrid environments.
Recall check: answer these from memory first
Give a one-line distinction between declarative desired-state configuration and imperative scripting.
Name four advantages of infrastructure as code and the organisational problem each one solves.
Explain in one sentence how Terraform manages multi-cloud and hybrid workflows with a single workflow.
What it tests. The concept of infrastructure as code: defining infrastructure in version-controlled configuration and applying it with a tool rather than by hand, and the difference between declarative desired-state configuration and imperative scripting. It also tests the advantages of IaC, such as repeatability, reviewable change and reduced drift, and how Terraform manages multi-cloud, hybrid and service-agnostic workflows through provider plugins under one constant workflow.
How to study it. Get the declarative versus imperative distinction crisp: Terraform describes the desired end state and reconciles reality toward it, rather than listing steps to run. Then learn the advantages as answers to problems, not a list, so you can match a stated pain (drift, no audit trail, environment sprawl) to the IaC benefit that addresses it. Be ready to explain why one language and workflow across AWS, Azure and on-premises reduces tool sprawl.
Easy to confuse
Declarative versus imperative infrastructure. Declarative configuration states the desired end result and lets the tool work out the steps and order; imperative scripting lists the commands to run. Terraform is declarative, so a scenario asking for desired-state, reconciled configuration points to Terraform rather than a shell script.
Multi-cloud versus hybrid cloud. Multi-cloud means using more than one public cloud provider; hybrid cloud combines public cloud with on-premises or private infrastructure. Both are managed by the same Terraform workflow through different providers, and the exam checks you can name which situation a scenario describes.
Worked example from the TF-Associate-004 bank
lock_openFree sampleInfrastructure as Code (IaC) with Terraformeasy
A team has been provisioning identical staging and production environments by clicking through the cloud console by hand, and the two environments keep ending up subtly different. They decide to define the whole environment once as Terraform configuration and apply it to each environment. Which advantage of IaC most directly addresses their problem?
AFaster raw provisioning speed, because Terraform always creates cloud resources more quickly than the console does.
BRepeatability, because applying the same configuration produces the same environment every time it is run.check_circle Correct
CAutomatic cost reduction, because Terraform selects the cheapest resource sizes on the team's behalf.
DElimination of the need for any cloud provider credentials during provisioning.
Repeatability means applying the same Terraform configuration reliably reproduces the same environment, removing manual inconsistency. Because the environment is expressed as code and Terraform converges real infrastructure to that declared configuration, reapplying the same files yields the same result each time, which is the mechanism that keeps staging and production identical.
Why A is wrong: Speed can improve, but Terraform is not guaranteed to be faster than the console, and speed is not what fixes environments that differ from each other.
Why B is correct: Defining the environment as code and reapplying it gives a repeatable, reproducible build, which is exactly what removes the subtle differences between the two environments.
Why C is wrong: Terraform provisions whatever sizes the configuration specifies and does not choose cheaper options by itself, so this does not address inconsistency.
Why D is wrong: Terraform still authenticates to the provider with credentials to make changes, so this is factually wrong and unrelated to environment consistency.
What you must be able to do. Declare and version providers, explain how a provider plugin works, configure multiple providers with alias, and say what state is for.
In one sentenceThe building blocks: providers declared and pinned in required_providers and the lock file, provider plugins mapping resources onto an API, aliasing multiple providers, and the purpose of state.
Recall check: answer these from memory first
Say where a provider's source address and version constraint are declared, and what the lock file adds.
Explain how you configure two provider configurations for two regions and how a resource selects the non-default one.
State in one line what Terraform state is for and why it must not be casually hand-edited.
What it tests. How Terraform uses providers: the required_providers block declaring each provider's source address and version constraint, terraform init installing them, and the dependency lock file pinning exact versions across machines. It tests writing configuration with multiple providers distinguished by alias and selected through a resource's provider meta-argument, and why Terraform keeps state as the authoritative map of configuration to real resources.
How to study it. Learn where a provider is declared (required_providers inside the terraform block) versus configured (a provider block with credentials and region), because the exam separates the two. Understand version constraint operators and why the lock file pins a provider so every machine and run uses the same version. For multiple providers, practise predicting which configuration a resource uses given an alias. Fix the idea that state is authoritative for what Terraform manages and must not be hand-edited casually.
Easy to confuse
required_providers block versus provider block. required_providers, inside the terraform block, declares each provider's source and version constraint; a separate provider block configures a declared provider with credentials and settings such as region. The exam tests whether you put versioning where configuration belongs, or the reverse.
Version constraint versus the dependency lock file. A version constraint in required_providers says which versions are acceptable; the .terraform.lock.hcl lock file records the exact version init selected, so runs are reproducible. The constraint is your intent, the lock file is the pinned result, and only init updates the lock file.
Provider alias versus a second provider. alias creates an additional configuration of the same provider, for example a second AWS region, and a resource opts in through its provider meta-argument. It is still one provider plugin, not a different provider, which is the distinction the exam draws.
Worked example from the TF-Associate-004 bank
lock_openFree sampleTerraform fundamentalseasy
A practitioner writes a new configuration that declares an aws_s3_bucket resource but never adds a required_providers entry or a provider block for AWS. They run terraform init in the empty working directory. What does Terraform do about the AWS provider?
AIt infers the provider from the resource type prefix and downloads the hashicorp/aws plugin from the registry during init.check_circle Correct
BIt fails init immediately because every provider must be pinned in a required_providers block before any plugin can be installed.
CIt skips provider installation entirely and defers downloading the plugin until the first terraform apply is run.
DIt prompts the practitioner to type the provider source address interactively before continuing the initialisation.
Terraform infers a provider from a resource type prefix and installs the plugin during init even without an explicit required_providers entry. A resource type such as aws_s3_bucket carries the provider local name as its prefix; Terraform resolves that to the default hashicorp/aws source address and installs the plugin during terraform init, which is the phase responsible for provider installation.
Why A is correct: Terraform maps the aws_ prefix to the aws provider, resolves it to the default hashicorp namespace, and installs the plugin during init even without an explicit required_providers entry.
Why B is wrong: Pinning in required_providers is best practice for version control, but its absence does not stop init; Terraform can still infer and install the provider, so this overstates the requirement.
Why C is wrong: Plugin installation is the job of init, not apply; deferring it to apply would leave the working directory uninitialised, so this misplaces when the download happens.
Why D is wrong: Terraform init is non-interactive for provider resolution and infers the source automatically, so it never pauses to ask the user to type a source address.
What you must be able to do. Place every core command correctly around write, plan, apply, and know exactly which commands change real infrastructure and which do not.
In one sentenceThe core loop: write, plan, apply, with init, validate, fmt and destroy placed correctly around it, and a firm grip on which step actually changes infrastructure.
Recall check: answer these from memory first
List the three steps of the core workflow and place init, validate, fmt and destroy around them.
Name every core command that changes real infrastructure, and confirm the rest do not.
Say when re-running terraform init is required.
What it tests. The core workflow of write, plan, apply and the role of each command around it. It tests terraform init (installs providers, downloads modules, initialises the backend, changes nothing), validate (syntax and consistency, no provider access), fmt (canonical style only), plan (previews create, update, replace and destroy actions and changes nothing), apply (executes the plan and updates state), and destroy (removes state-tracked resources). Reading plan output and knowing a saved plan can be passed to apply are in scope.
How to study it. Build a mental map of the workflow and pin each command to its place and its effect. The single most tested idea is which step changes infrastructure: only apply and destroy do. Practise reading plan symbols for create, update in place, replace and destroy, and know that plan and validate are safe to run anywhere. Learn when init must be re-run (new provider or module, backend change) and what a saved plan file gives you when passed to apply.
Easy to confuse
terraform init versus terraform apply. init prepares the working directory by installing providers and modules and initialising the backend, and creates no infrastructure; apply executes planned actions and changes real resources. A scenario that provisions anything needs apply, not init, which is the exam's most common workflow trap.
terraform validate versus terraform plan. validate checks syntax and internal consistency with no provider or state access and needs no credentials; plan contacts providers, refreshes real resources and diffs against state to preview changes. If the question stresses no credentials or offline checking, it is validate.
terraform plan versus terraform apply. plan previews the actions and writes nothing; apply carries them out and updates state. A saved plan file from plan can be handed to apply so it executes exactly those actions with no re-prompt, but plan on its own never changes anything.
Worked example from the TF-Associate-004 bank
lock_openFree sampleCore Terraform workflowmedium
An engineer runs 'terraform apply' with no extra flags in a directory using the local backend. Terraform prints the proposed plan and then pauses. What must happen before Terraform makes any changes to the real infrastructure?
$ terraform apply
# aws_instance.web will be created
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
ATerraform applies the changes immediately because a plan was already generated during the same command.
BThe engineer must re-run the command with 'terraform apply -refresh-only' to confirm the intended changes.
CTerraform waits for the engineer to run 'terraform plan' in a second terminal to release the pause.
DThe engineer must type 'yes' at the interactive approval prompt before Terraform provisions the resources.check_circle Correct
A plain terraform apply presents a plan and requires explicit interactive approval before changing infrastructure. By default terraform apply computes a plan, displays it, and blocks on an interactive confirmation; only after the operator types 'yes' does it call the providers to create, update, or destroy real resources.
Why A is wrong: Tempting because apply does generate its own plan, but without a saved plan file or -auto-approve it still stops and asks for confirmation first.
Why B is wrong: Refresh-only only reconciles state with real infrastructure and proposes no resource changes, so it would never provision the new instance.
Why C is wrong: A separate plan run has no effect on the waiting apply, which is blocked purely on the interactive yes-or-no approval prompt.
Why D is correct: Correct: a bare 'terraform apply' shows the plan and waits for the operator to type 'yes' before it executes any changes.
What you must be able to do. Author configuration with resources, data sources, variables, outputs, complex types, expressions, dependencies, custom conditions, and handle sensitive data correctly.
In one sentenceThe largest domain: resource versus data blocks, variables and outputs with fixed precedence, complex types and expressions, implicit versus explicit dependencies, custom conditions, and sensitive data that is still plaintext in state.
Recall check: answer these from memory first
State the variable precedence order from highest to lowest.
Distinguish a resource block from a data source in one line, and an argument from an attribute.
Explain what marking a value sensitive does and does not do to that value in state.
What it tests. Writing configuration: resource blocks that manage objects versus data blocks that read existing information, referencing attributes to wire values and create implicit dependencies, input variables and outputs including variable precedence and sensitive marking, complex collection and structural types, dynamic configuration with expressions, functions and dynamic blocks, declaring dependencies with depends_on when references cannot express them, custom conditions (variable validation, preconditions, postconditions, check blocks), and managing secrets including sourcing from Vault.
How to study it. This is the heaviest domain, so give it the most time. Memorise variable precedence in order: a -var or -var-file on the command line wins, then a TF_VAR_ environment variable, then terraform.tfvars and auto.tfvars files, then the variable default. Drill resource versus data (manage versus read) and argument versus attribute (set in configuration versus exported after apply). Learn that references create implicit dependencies and depends_on is only for orderings the configuration cannot express. Fix firmly that sensitive hides values from output but state still stores them in plaintext, so protecting state is the real control.
Easy to confuse
Resource block versus data block. A resource block creates and manages an object over its lifecycle; a data block reads existing information and manages nothing, refreshing during plan to produce read-only attributes. If the scenario needs to look something up rather than own it, it is a data source.
Implicit dependency versus depends_on. An implicit dependency comes from one resource referencing another's attribute and is the preferred way to order operations; depends_on declares an ordering Terraform cannot infer from references. Over-using depends_on harms parallelism, so it is a last resort, not a default.
sensitive marking versus protecting state. Marking a variable or output sensitive suppresses it in plan and apply output, but the value is still written to state in plaintext. sensitive is not encryption, so the exam wants protecting the state file, or sourcing secrets from Vault, named as the actual safeguard.
Worked example from the TF-Associate-004 bank
lock_openFree sampleTerraform configurationmedium
A practitioner defines a variable to hold two Availability Zones and iterates over it with for_each to create one subnet per zone. When they run terraform plan, Terraform reports that for_each cannot be used with this value. What change to the variable makes for_each work directly?
AChange the variable type to tuple([string, string]), because a fixed-length tuple is the collection for_each expects.
BChange the variable type to set(string), because for_each accepts a map or a set of strings, not a list.check_circle Correct
CLeave the type as list(string) and add a lifecycle block with create_before_destroy set to true.
DLeave the type as list(string) and reference each.key instead of each.value in the resource.
Recognise that for_each accepts a map or a set of strings, so a list must be converted to a set before iterating over it. for_each keys each instance by a stable string, which a map or set of strings provides but a list does not; converting the list to set(string) supplies acceptable keys and lets the iteration proceed.
Why A is wrong: A tuple looks like an ordered pair that might suit two zones, but for_each rejects tuples just as it rejects lists; it needs a map or a set.
Why B is correct: for_each requires a map or a set of strings; converting the list to a set of strings gives it a collection it can key by value, so it works directly.
Why C is wrong: create_before_destroy governs replacement ordering and does nothing about the for_each input type, so the plan would fail with the same error.
Why D is wrong: Swapping each.key for each.value does not change that a raw list is an invalid for_each argument, so Terraform still refuses the list.
What you must be able to do. Source modules from local paths and registries, reason about input and output scope, call modules in configuration, and pin module versions deliberately.
In one sentenceComposing configuration: sourcing modules locally or from a registry, the input-and-output boundary that encapsulates a module, calling modules, and pinning versions so upgrades are deliberate.
Recall check: answer these from memory first
Name the kinds of source a module block can use and say which step retrieves the module.
Explain how values get into and out of a module, and why a parent cannot reach a child's resources directly.
Say which modules the version argument applies to and why pinning matters.
What it tests. How Terraform sources modules through the source argument (local path, public or private registry, Git or HTTP) with init retrieving them, variable scope within modules (a module receives values only through input variables and exposes them only through outputs, so a parent cannot reach a child's internal resources), using module blocks to pass inputs and reference module.name.output including count and for_each on modules, and managing module versions with the version argument for registry modules.
How to study it. Distinguish a local module from a registry module and remember that changing the source argument requires re-running init. Fix the encapsulation model: values flow in through input variables and out through outputs, and nothing else crosses the boundary, which is the whole point of a module. Practise calling a module and referencing its outputs as module.name.output, and know count and for_each apply to module blocks. For versioning, note the version argument is for registry modules and that pinning protects you from an unexpected upstream change.
Easy to confuse
Local module versus registry module. A local module is sourced by a relative path in the same repository and is not versioned by a registry; a registry module is sourced by a registry address and supports the version argument. Only registry modules take version constraints, which the exam uses to test the difference.
Module input and output versus reaching inside a module. A module communicates only through its declared input variables and outputs; a parent cannot reference a child module's internal resource attributes directly. If a scenario needs a value out of a module, the module must expose it as an output, which is the encapsulation the exam checks.
Worked example from the TF-Associate-004 bank
lock_openFree sampleTerraform modulesmedium
A practitioner adds a module block that points at a subdirectory of the current project, then runs 'terraform init'. What does Terraform do to retrieve this module?
module "network" {
source = "./modules/network"
}
AIt queries the public Terraform Registry for a module named 'network' and downloads the newest matching version into the cache.
BIt reads the module directly from the given relative path on disk without downloading anything, because a source beginning with './' is a local path.check_circle Correct
CIt clones the path as a Git repository into the '.terraform/modules' directory before the configuration can be used.
DIt copies the subdirectory into '.terraform/modules' and thereafter ignores later edits to the original files.
A module source beginning with './' or '../' is a local path that Terraform reads directly without any download. Terraform classifies each module source by its syntax. A relative path prefixed with './' or '../' denotes a local module, so init resolves it against the working directory on disk and never contacts the registry or a remote host.
Why A is wrong: Registry retrieval is tempting because init does fetch registry modules, but a registry source must be a namespaced address such as 'namespace/name/provider', not a relative path.
Why B is correct: A source starting with './' or '../' is a local path, so Terraform reads the files in place during init and performs no download.
Why C is wrong: Git cloning happens only for a Git source address, and a leading './' is never interpreted as a Git URL, so no clone occurs for a local path.
Why D is wrong: This sounds plausible because remote modules are cached under '.terraform/modules', but local modules are referenced in place and edits are picked up on the next run.
What you must be able to do. Explain the local backend and its limits, describe state locking, configure remote state with a backend block, and manage drift with the right state commands.
In one sentenceState in practice: the default local backend and why teams outgrow it, state locking, remote state via the backend block, and handling drift with refresh, state mv and rm, and -replace.
Recall check: answer these from memory first
Give two reasons the local backend is unsuitable for a team.
Say what state locking prevents and what force-unlock is for.
Name the command to force a single resource to be recreated on the next apply, and the deprecated command it replaces.
What it tests. Managing state: the default local backend storing terraform.tfstate on disk and its limits for teams, state locking that stops concurrent applies corrupting state and depends on the backend, configuring remote state with a backend block (for example S3 or HCP Terraform via cloud) for shared state and locking with migration on init, and managing drift, where real-world change diverges from state, using refresh, terraform state mv and rm, and the -replace option, plus why hand-editing state is dangerous.
How to study it. Understand why the local backend does not suit teams: state sits on one machine and there is no shared locking across people, so remote state is preferred for collaboration. Learn what locking protects against and what -lock and force-unlock do. Know that changing the backend requires terraform init and that Terraform can migrate existing state. For drift, learn refresh reconciles state with reality and plan surfaces drift as proposed changes, and reach for -replace rather than the deprecated taint to force recreation. Treat state mv and rm as surgical tools and never hand-edit the file.
Easy to confuse
Local backend versus remote backend. The local backend keeps terraform.tfstate on one machine with no shared locking; a remote backend such as S3 or HCP Terraform gives shared state and locking for a team. A collaboration scenario points to remote state, and switching backends needs terraform init.
-replace versus taint. -replace, given to plan or apply, marks a resource for recreation on the next run and is the current approach; the taint command did the same but is deprecated in 004. When a question offers both, the exam wants -replace, so treat taint as the older-version trap.
terraform state mv versus terraform state rm. state mv renames or moves an object within state, keeping it managed; state rm removes an object from state so Terraform stops managing it without destroying the real resource. The exam checks you pick the one that matches the stated outcome.
Worked example from the TF-Associate-004 bank
lock_openFree sampleTerraform state managementeasy
A practitioner runs 'terraform apply' in a new directory that contains only 'main.tf', with no 'backend' or 'cloud' block declared. After the apply succeeds, where does Terraform record the resulting state by default?
AIn a file named 'terraform.tfstate' in the current working directory, using the local backend.check_circle Correct
BIn HCP Terraform, because any workspace is automatically linked to the remote state service.
CIn the provider's own datastore, since the 'local' provider manages where state is persisted.
DNowhere on disk, because state is held only in memory until a backend is added.
When no backend is configured, Terraform defaults to the local backend and stores state in terraform.tfstate on disk. The local backend is Terraform's built-in default. When neither a 'backend' nor a 'cloud' block is present, Terraform persists the working state to a file called terraform.tfstate in the current directory after every successful operation.
Why A is correct: With no backend or cloud block configured, Terraform uses the local backend by default and writes state to 'terraform.tfstate' in the working directory.
Why B is wrong: HCP Terraform is only used when a 'cloud' block is present; without one Terraform never links a workspace to a remote service, so this is wrong.
Why C is wrong: It is tempting to conflate the 'local' provider with the local backend, but providers manage resources and never decide where state is stored.
Why D is wrong: Terraform always persists state after an apply; the default local backend writes it to disk immediately rather than keeping it only in memory.
What you must be able to do. Import existing infrastructure into state, use read-only CLI commands to inspect state, and enable verbose logging when diagnosing behaviour.
In one sentenceKeeping infrastructure running: importing unmanaged resources into state (which does not write your configuration), read-only state inspection, and environment-variable-driven verbose logging.
Recall check: answer these from memory first
Say what terraform import does and does not do, and name the two ways to import.
Match terraform state list, terraform state show and terraform show to the question each one answers.
Name the environment variables that control verbose logging and where output goes.
What it tests. Maintaining running infrastructure: importing existing resources into Terraform with the terraform import command or an import block, after which configuration must be written to match the imported object, inspecting state read-only with terraform state list and terraform state show and rendering state or a saved plan with terraform show, and using verbose logging controlled by the TF_LOG environment variable at levels such as TRACE and DEBUG with TF_LOG_PATH to write logs to a file.
How to study it. Fix the key limit of import: it populates state but does not generate configuration, so you still write matching configuration yourself, and the import block is the current, plan-reviewable way to do it. Sort the read-only inspection commands by what each answers: state list for what is managed, state show for one resource's attributes, terraform show for whole state or a saved plan. Remember logging is controlled by environment variables (TF_LOG, TF_LOG_PATH), not a configuration argument, which is a common trap.
Easy to confuse
Import populating state versus writing configuration. Import brings an existing resource into state so Terraform manages it, but it does not write the resource block for you; you must author configuration that matches the imported object. The exam plants the belief that import generates configuration, and it does not.
terraform import command versus import block. The terraform import command imports imperatively at the CLI; an import block declares the import in configuration so it is previewed in plan and applied like other changes. The block is the current, reviewable approach the 004 exam favours.
TF_LOG environment variable versus a configuration setting. Verbose logging is turned on by the TF_LOG environment variable and directed to a file by TF_LOG_PATH, not by any argument in the configuration. A scenario that tries to enable logging inside a .tf file is the trap.
Worked example from the TF-Associate-004 bank
lock_openFree sampleMaintain infrastructure with Terraformmedium
A practitioner has applied a configuration that manages roughly forty resources and wants to see the full list of resource addresses currently tracked in state, without printing any attribute values or changing anything. Which command produces exactly this?
Aterraform show
Bterraform state listcheck_circle Correct
Cterraform state show
Dterraform plan
Use terraform state list to enumerate the resource addresses tracked in state without printing attribute values. terraform state list walks the state file and emits each managed resource's address, giving an index of what Terraform tracks; it is read-only and outputs no attribute data, which distinguishes it from terraform show.
Why A is wrong: terraform show does read state read-only, but it prints the full human-readable attributes of every resource rather than a bare list of addresses, which is more than was asked for.
Why B is correct: terraform state list reads the current state and prints one resource address per line for every tracked resource, with no attribute values and no modification to state.
Why C is wrong: terraform state show requires a specific resource address argument and prints that one resource's attributes, so it cannot enumerate the whole list of addresses.
Why D is wrong: terraform plan compares configuration against state and refreshes it to compute a diff, so it does extra work and does not simply list the addresses held in state.
What you must be able to do. Use HCP Terraform to run Terraform remotely with managed state, and match a governance or organisation need to the right HCP Terraform feature.
In one sentenceThe managed platform: HCP Terraform (formerly Terraform Cloud) running remotely with managed state, its collaboration and governance features, workspaces and projects, and VCS and API integrations.
Recall check: answer these from memory first
Give the current name for the product formerly called Terraform Cloud and say how a remote run differs from a local apply.
Match policy as code, cost estimation and private registries to the governance need each one meets.
Distinguish an HCP Terraform workspace from a Terraform CLI workspace.
What it tests. Using HCP Terraform: remote runs with managed state connected through the cloud block or a VCS workflow, collaboration and governance features (remote state sharing, policy as code with Sentinel or OPA, cost estimation, private module and provider registries), organising work with workspaces (each holding its own state, variables and run history) and projects that group workspaces, and integrations such as VCS-driven plans on pull requests, run triggers between workspaces, notifications, and CLI-driven or API-driven runs.
How to study it. Learn HCP Terraform as the current product name and treat Terraform Cloud as the old label the distractors use. Understand how a remote run differs from a local apply and how the cloud block or a VCS connection wires it up. Match each governance need to its feature: policy as code with Sentinel or OPA for guardrails, cost estimation for spend, private registries for internal sharing. Most importantly, separate an HCP Terraform workspace, which holds its own state, from a Terraform CLI workspace, which only switches state within one backend.
Easy to confuse
HCP Terraform versus Terraform Cloud. HCP Terraform is the current product name for what was called Terraform Cloud. They are the same platform, but 004 uses the new name, so an option still saying Terraform Cloud is usually the older-version distractor.
HCP Terraform workspace versus Terraform CLI workspace. An HCP Terraform workspace is an organising unit that holds its own state, variables and run history on the platform; a Terraform CLI workspace only switches between named states within a single backend locally. The exam contrasts the two directly, so do not treat them as the same thing.
Sentinel and OPA versus cost estimation. Sentinel and OPA are policy-as-code engines that enforce rules on a run as guardrails; cost estimation reports the spend impact of a plan. Both are governance features, but the exam wants the enforcement mechanism separated from the reporting one.
Worked example from the TF-Associate-004 bank
lock_openFree sampleHCP Terraformmedium
A platform team wants every run in an HCP Terraform workspace to be blocked from applying if a proposed AWS security group opens port 22 to the whole internet. They want this enforced automatically as part of the run, before the apply stage. Which HCP Terraform feature should they use?
# proposed change flagged during plan
resource "aws_security_group_rule" "ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
AA policy as code check using Sentinel or OPA, attached to the workspace so it evaluates the plan between the plan and apply stages.check_circle Correct
BThe cost estimation feature, which inspects the plan and refuses to apply resources that create a security risk.
CA private module registry constraint that rejects any module publishing a rule with an open CIDR block.
DA workspace run trigger that fires a downstream workspace to revert the offending rule after the apply completes.
Policy as code with Sentinel or OPA in HCP Terraform enforces governance rules against a plan and can block an apply. HCP Terraform evaluates attached Sentinel or OPA policy sets against the plan output during the run, and a hard-mandatory policy that fails prevents the apply stage from proceeding, which is precisely the automated gate the team needs.
Why A is correct: Sentinel and OPA are HCP Terraform's policy as code engines; a policy set attached to the workspace runs against the plan and can produce a hard-mandatory failure that blocks the apply.
Why B is wrong: Cost estimation is a genuine HCP Terraform feature and runs at a similar point in the run, which makes it tempting, but it only reports projected spend and never blocks a run for a security condition.
Why C is wrong: The private registry hosts and versions shared modules and providers, so it sounds governance related, but it does not evaluate the contents of a plan or enforce rules at run time.
Why D is wrong: Run triggers do chain workspaces together, which feels like automation, but they act after a run finishes and cannot prevent the risky apply from happening in the first place.
A study plan that works
Map the objectives and confirm you are studying 004
Day 1
Read the official Exam Review for Associate 004 and the eight objective groups. Deliberately set aside any 002 or 003 material: check that your resources say HCP Terraform rather than Terraform Cloud and prefer -replace over taint. Book a provisional exam date now, because a fixed date turns open-ended study into a plan.
Ground the concepts and fundamentals (Objectives 1 and 2)
Week 1
Lock down infrastructure as code, declarative versus imperative, and the advantages, then providers: required_providers versus a provider block, version constraints and the lock file, aliasing multiple providers, and what state is for. Use the recall prompts in this guide: cover the summary, answer from memory, then reveal.
Drill the core workflow until it is automatic (Objective 3)
Week 1-2
Run init, validate, fmt, plan, apply and destroy against a real provider and watch what each does. Fix the single most tested idea: only apply and destroy change infrastructure. Practise reading plan symbols for create, update, replace and destroy, and know when init must be re-run.
Go deep on configuration (Objective 4)
Week 2-3
This is the heaviest domain. Memorise variable precedence, drill resource versus data and argument versus attribute, practise complex types, expressions and dynamic blocks, and know depends_on is a last resort. Fix that sensitive hides output but state stays plaintext.
Cover modules, state and maintenance (Objectives 5, 6 and 7)
Week 3-4
Learn module sourcing and the input-output boundary, then state: local versus remote backends, locking, backend migration on init, and drift handling with refresh, state mv and rm, and -replace. Add import (populates state, does not write configuration), read-only inspection commands, and TF_LOG logging.
Learn HCP Terraform and practise on scenarios (Objective 8)
Week 4
Cover HCP Terraform: remote runs and managed state, Sentinel and OPA, cost estimation, private registries, and workspaces versus projects. Then move to full practice sets and read the explanation for every question, including the ones you got right, because the marks are in knowing why each distractor is wrong.
Sit a timed mock and close weak objectives
Week 5
Take at least one full timed mock to rehearse pacing and flag-and-return. Use your per-objective accuracy to drill the groups dragging you down rather than re-reading what you already know, and review every missed question before booking or sitting.
Know when you're ready
Readiness for Terraform Associate 004 is a score on questions you have not seen before, not a feeling that the material is familiar. Those are different things, and the gap between them is where people fail. Re-reading the docs builds fluency, and fluency feels like knowledge, so confidence rises while real recall does not. The fix is to test yourself: if you can answer fresh scenario questions and explain why the wrong options are wrong, you know it; if you can only nod along to an explanation, you do not yet.
Be especially wary of two traps on this exam. First, hands-on experience can make you overconfident on the exact wording: you know that apply changes infrastructure, but the exam will test whether init or plan does, and the precise boundaries are what earn marks. Second, older knowledge sits badly with 004: if your instinct still says Terraform Cloud or taint, retrain it before you sit, because those are exactly the distractors. Trust your measured per-objective accuracy over your gut, and aim to clear every objective group comfortably on unseen questions across more than one session.
This guide gives you the map. The practice bank is where you find out whether you can navigate it, with an explanation of why the right answer is right and every wrong one is wrong on every question. Readiness scoring tells you when you are there. Not before.
Ready to put this into practice?
Free TF-Associate-004 questions, every answer explained. No sign-up.
Answer as 004, not 002 or 003. Prefer HCP Terraform over Terraform Cloud and -replace over taint; the outdated term is usually the distractor.
Ask which step changes infrastructure. Only apply and destroy do; init, validate, plan and fmt change nothing, and questions turn on that line.
Know variable precedence cold: command-line -var or -var-file beats TF_VAR_ environment variables, which beat terraform.tfvars and auto.tfvars files, which beat defaults.
Remember sensitive hides values from output but state still stores them in plaintext, so protecting state is the real control, not the sensitive flag.
Read the last line of the question first. It tells you what is actually being asked, so you can read the scenario looking for the answer.
Choose the most appropriate option, not merely a correct one. Several options are often true statements about Terraform; only one fits the scenario.
Flag and move on. Do not lose time on one hard item when easier marks are waiting; cover every question first, then return.
Frequently asked questions
Is the Terraform Associate 004 exam hard?
It is an associate exam that rewards understanding the workflow over deep memorisation, so hands-on practice makes it very approachable. The difficulty is precision: knowing exactly which command does what and choosing the best option among plausible ones, which is why scenario practice that explains every option matters.
How long should I study for Terraform Associate 004?
Most candidates with some Terraform experience are ready in two to four weeks of focused study. With no hands-on time, budget more and spend it running init, plan and apply against a real provider, because the exam tests what the commands actually do.
What is the difference between 004 and the older 002 or 003 exams?
Version 004 is the current exam and it tracks a recent Terraform release. The visible changes are terminology and current practice: HCP Terraform is the product name rather than Terraform Cloud, -replace is preferred over the deprecated taint, and the import block sits alongside the terraform import command. Most third-party material is 002 or 003 era, so study 004 sources.
Do I need cloud experience or coding to pass?
You do not need to write application code, but hands-on experience with at least one provider such as AWS, Azure or GCP makes the material far quicker to absorb. The exam is about Terraform itself, so being comfortable with the write, plan, apply loop matters more than deep cloud knowledge.
What is the passing score for Terraform Associate 004?
HashiCorp does not publish a fixed passing score or a fixed question count for this exam, so treat any specific number you see elsewhere with caution. Aim to clear every objective group comfortably on unseen practice questions rather than chasing a target percentage.
Which objectives should I focus on?
Configuration and the core workflow carry the most practical weight, so give them the most time: variable precedence, resource versus data, dependencies, and which command changes infrastructure. Any per-objective weighting in this guide is an examworthy estimate, not an official HashiCorp figure, because HashiCorp does not publish one.
Should I learn -replace or taint for recreating a resource?
Learn -replace, given to terraform plan or apply, because it is the current approach in 004. The taint command did the same job but is deprecated, so when both appear as options the exam wants -replace and treats taint as the older-version trap.
Does marking a variable sensitive protect it in state?
No. Marking a value sensitive suppresses it in plan and apply output, but Terraform still writes it to state in plaintext. Protecting the state file, and sourcing secrets from a system such as Vault rather than committing them, are the real safeguards.
Is the Terraform Associate certification worth it?
It is a recognised, practical credential for cloud, platform, DevOps and SRE engineers who want to prove hands-on Terraform fluency. The workflow and state concepts it covers are the ones you use daily, so it doubles as a solid foundation before more advanced infrastructure automation work.
Examworthy is not affiliated with or endorsed by HashiCorp. This guide is original study material based on the public exam blueprint. We never reproduce live exam items. TF-Associate-004 and related marks belong to their respective owners.