24 real TF-Associate-004 sample questions, each with an explanation of why every option is right or wrong. No account, no card. This is the reasoning the TF-Associate-004 tests: knowing why the tempting answer is wrong, not just spotting the right one.
The real TF-Associate-004 is Not published by HashiCorp questions in 60 minutes. For a domain-by-domain breakdown and a study plan, read the TF-Associate-004 study guide. The full bank has 294 questions.
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?
variable "azs" {
type = list(string)
default = ["eu-west-1a", "eu-west-1b"]
}
resource "aws_subnet" "this" {
for_each = var.azs
availability_zone = each.value
}
- 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.
lock_openFree sampleTerraform configurationmedium
An engineer wraps a list of tags with toset() before passing it to for_each. The source list contains the value "web" twice. What does Terraform do with the duplicate when it builds the instances?
resource "aws_instance" "app" {
for_each = toset(["web", "db", "web"])
tags = { role = each.value }
}
- ATerraform creates three instances and appends a numeric suffix to the second "web" key to keep the addresses unique.
- BTerraform raises an error during plan because the set passed to for_each contains a duplicate element.
- CTerraform collapses the duplicate, so two instances are created keyed by "web" and "db".check_circle Correct
- DTerraform creates three instances because for_each preserves every element of the original list regardless of the toset wrapper.
Understand that a set stores only distinct values, so converting a list with duplicates to a set reduces the number of for_each instances. Set semantics guarantee uniqueness, so building a set from a list with a repeated value drops the repeat; for_each then iterates the distinct members only, yielding one instance per unique tag.
Why A is wrong: This assumes list-style indexing survives the conversion, but converting to a set discards ordinal positions, so no suffixing occurs and only two instances result.
Why B is wrong: Duplicates are silently de-duplicated by set construction rather than reported, so the plan succeeds instead of failing.
Why C is correct: A set holds only distinct values, so toset removes the repeated "web" and for_each produces one instance per unique element, giving two.
Why D is wrong: This ignores that toset changes the type; the set no longer contains a repeated element, so three instances cannot be produced.
lock_openFree sampleTerraform configurationmedium
A module input is typed as an object with two required attributes. A caller passes a value that includes those two attributes plus an extra attribute the object type does not declare. What does Terraform do when it validates this input?
variable "server" {
type = object({
name = string
size = number
})
}
module "app" {
source = "./app"
server = { name = "api", size = 2, region = "eu-west-1" }
}
- AIt accepts the value and silently keeps the extra region attribute available inside the module.
- BIt coerces the value into a map(string), converting size and region to strings to accommodate the extra key.
- CIt accepts the value and drops the extra region attribute, warning that the input contained an unused key.
- DIt rejects the value because the supplied object contains an attribute not present in the declared object type.check_circle Correct
Recognise that an object type enforces its declared attribute set, so a value with an undeclared attribute is a type error. Object types describe an exact set of named attributes, and type checking fails when a value supplies an attribute outside that set rather than ignoring or absorbing it, which is what distinguishes an object from a map.
Why A is wrong: This treats an object like a free-form map, but object types are constrained to their declared attributes, so an undeclared attribute is not carried through untouched.
Why B is wrong: A caller might expect fallback to a map, but Terraform does not silently retype a declared object as a map; it enforces the object schema instead.
Why C is wrong: Terraform does not quietly discard surplus attributes with a warning; a surplus attribute is a type error that stops the run.
Why D is correct: An object type is a strict schema; a value carrying an attribute the type does not declare fails type checking, so Terraform reports the mismatch.
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.
lock_openFree sampleCore Terraform workflowmedium
A CI pipeline runs Terraform non-interactively and must apply an already-reviewed change without any human at a keyboard to confirm the prompt. Which single command lets the apply proceed unattended while still executing the changes?
# runs inside an automated CI job, no TTY attached
- ARun 'terraform apply -auto-approve' so Terraform skips the interactive prompt and applies the change.check_circle Correct
- BRun 'terraform plan -auto-approve' so the plan step approves itself for the later apply.
- CRun 'terraform apply -input=false' so Terraform treats the confirmation as automatically granted.
- DRun 'terraform apply -lock=false' so the run does not stop to wait for operator confirmation.
The -auto-approve flag on terraform apply skips the interactive confirmation so changes apply unattended. In automation Terraform cannot receive keyboard input for the confirmation prompt; passing -auto-approve to apply causes it to accept the generated plan and execute the changes without waiting for a typed yes.
Why A is correct: Correct: -auto-approve tells apply to bypass the yes prompt, which is exactly what an unattended pipeline needs.
Why B is wrong: Tempting because -auto-approve is the right flag, but plan never changes infrastructure and does not accept that flag, so nothing would be applied.
Why C is wrong: The -input=false flag only disables prompting for missing variables; with no approval given the apply errors out rather than proceeding.
Why D is wrong: Disabling the state lock affects concurrency safety, not the approval prompt, so apply would still halt waiting for a yes.
lock_openFree sampleCore Terraform workflowmedium
A practitioner runs 'terraform plan -out=tfplan', reviews the output, then runs 'terraform apply tfplan'. What is Terraform's behaviour when apply is given that saved plan file?
$ terraform plan -out=tfplan
$ terraform apply tfplan
- ATerraform discards the saved plan, recomputes a fresh plan, and prompts for approval before applying.
- BTerraform applies the saved plan without prompting for approval and then updates the state file.check_circle Correct
- CTerraform refuses to run because a saved plan file can only be inspected with 'terraform show', not applied.
- DTerraform still stops at the interactive prompt because approval is required for every apply regardless of input.
Applying a saved plan file executes it without prompting and updates state with the results. A saved plan file records an exact set of actions the operator already reviewed, so terraform apply treats it as pre-approved, skips the confirmation prompt, executes those actions, and records the new resource attributes in state.
Why A is wrong: Tempting because a bare apply does recompute and prompt, but supplying a saved plan file changes that behaviour entirely.
Why B is correct: Correct: a saved plan is already an approved set of actions, so apply executes it directly with no prompt and writes the results to state.
Why C is wrong: terraform show can inspect the file, but the same file is also the intended input to apply, so this claim is wrong.
Why D is wrong: Passing a saved plan is itself the approval, which is precisely the case where apply does not display a confirmation prompt.
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?
resource "aws_s3_bucket" "assets" {
bucket = "example-assets-bucket"
}
- 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.
lock_openFree sampleTerraform fundamentalseasy
An engineer needs to manage resources in two different AWS regions from a single configuration. They define one default aws provider for eu-west-1 and a second aws provider with an alias for us-east-1. How should a resource be told to use the us-east-1 configuration?
provider "aws" {
region = "eu-west-1"
}
provider "aws" {
alias = "us"
region = "us-east-1"
}
- ASet region = "us-east-1" directly inside the resource block so it overrides the default provider.
- BAdd a provider = aws.us meta-argument to the resource block to point it at the aliased provider.check_circle Correct
- CAdd a depends_on = [aws.us] entry so the resource is associated with the second provider.
- DRename the resource type to aws_us_instance so the alias is matched by the type prefix.
A resource selects a non-default provider configuration through the provider meta-argument referencing the provider local name and its alias. When multiple configurations of the same provider exist, one is default and the others carry an alias; a resource opts in to an aliased configuration by setting the provider meta-argument to localname.alias, here aws.us, rather than by any resource-level region setting.
Why A is wrong: Region is a provider argument, not a resource argument, and setting it on the resource is rejected; this confuses where regional configuration lives.
Why B is correct: The provider meta-argument with the local name and alias, written as aws.us, is exactly how a resource selects a non-default aliased provider configuration.
Why C is wrong: depends_on expresses ordering between resources or modules, not provider selection, so it cannot bind a resource to an aliased provider.
Why D is wrong: Resource type names are fixed by the provider schema and cannot encode an alias; inventing a type prefix would simply produce an unknown resource type error.
lock_openFree sampleTerraform fundamentalseasy
A team wants to avoid committing cloud credentials to their Terraform code. Their aws provider block currently has no access_key or secret_key arguments, and they rely on the AWS CLI environment variables already exported in their shell. What does the AWS provider do at plan and apply time?
provider "aws" {
region = "ap-southeast-2"
}
- AIt refuses to authenticate because credentials must be written into the provider block as literal arguments.
- BIt generates temporary credentials on its own by calling the AWS metadata service on the practitioner's laptop.
- CIt reads credentials from its supported sources, including the standard AWS environment variables, and authenticates with those.check_circle Correct
- DIt stores the credentials the team last used inside terraform.tfstate and reuses them on every run.
A provider can authenticate from external credential sources such as environment variables rather than requiring secrets written into the configuration. Providers accept authentication details through a resolution chain that typically includes explicit arguments, environment variables, and shared credential files; because the AWS provider honours the standard environment variables, an empty credentials block still authenticates without embedding secrets in code.
Why A is wrong: Hardcoding credentials in the block is one option but never a requirement; the provider supports several credential sources, so claiming it is mandatory is wrong.
Why B is wrong: The instance metadata service is only available on EC2 instances, not an ordinary laptop, so the provider cannot mint credentials that way in this scenario.
Why C is correct: The AWS provider follows a documented credential resolution chain that includes environment variables and shared config files, so exported variables let it authenticate without any in-code secrets.
Why D is wrong: State records resource attributes, not the operator credentials used to authenticate, so the provider does not source secrets from the state file.
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.
lock_openFree sampleTerraform modulesmedium
A team edits the source of an existing module block to point at a new registry version, then runs 'terraform plan' straight away without re-running init. What is the most likely outcome?
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.1.0"
}
- AThe plan silently uses the newly requested version because Terraform downloads modules automatically at plan time.
- BThe plan proceeds using the previously installed version and prints no warning, because the source change takes effect only on the next apply.
- CThe plan errors and asks the practitioner to run 'terraform init' because the module version currently installed does not satisfy the changed configuration.check_circle Correct
- DTerraform automatically re-runs init as part of plan, downloads the new version, and continues without any prompt.
Terraform installs modules during init, so changing a module source or version requires re-running init before plan can proceed. Module retrieval and installation occur only during terraform init. When the configured source or version no longer matches what is installed under '.terraform/modules', plan halts and instructs the user to run init to install the requested module.
Why A is wrong: This assumes plan performs retrieval, but module installation happens during init, so plan does not fetch the new version on its own.
Why B is wrong: It is tempting to think Terraform quietly keeps the old module, but it detects that the installed module no longer matches the configuration and stops rather than proceeding silently.
Why C is correct: Module retrieval is an init-time step, so a changed source or version that is not yet installed causes plan to fail and direct the user to run init first.
Why D is wrong: Plan never triggers init implicitly; the two are distinct commands, so Terraform will not fetch modules or providers as a side effect of planning.
lock_openFree sampleTerraform modulesmedium
Within a module block, what is the role of the source argument?
- AIt names the provider that the child module will use to create resources.
- BIt sets the version constraint that decides which release of the module Terraform installs.
- CIt defines the output values that the child module exposes back to the calling configuration.
- DIt tells Terraform where to retrieve the child module's configuration from, such as a local path or the Terraform Registry.check_circle Correct
The module source argument tells Terraform where to retrieve a child module's configuration from. Every module block must set source, which Terraform resolves during init to locate and copy the module's configuration files before planning; it is a location, not a version or provider setting.
Why A is wrong: This confuses source with provider configuration. The source argument locates the module code; provider selection is handled by required_providers and provider blocks, not by source.
Why B is wrong: Version constraints are expressed with the separate version argument, which applies only to registry modules. The source argument identifies where the module lives, not which release.
Why C is wrong: Outputs are declared with output blocks inside the child module. The source argument has nothing to do with exposing values; it only points at the module code.
Why D is correct: The source argument is the module's location, and Terraform reads it during init to fetch the module's files from a local path, registry, VCS, or other supported source.
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?
terraform {
required_providers {
local = {
source = "hashicorp/local"
}
}
}
resource "local_file" "note" {
filename = "${path.module}/note.txt"
content = "hello"
}
- 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.
lock_openFree sampleTerraform state managementeasy
A team of four engineers shares one module by copying the directory between laptops, each running 'terraform apply' against the same cloud resources using the default local backend. They keep clobbering each other's changes. What is the underlying cause tied to the local backend?
- AThe local backend encrypts terraform.tfstate, so only the machine that created it can decrypt and apply.
- BEach laptop holds its own separate terraform.tfstate file, and the local backend offers no shared storage or state locking across machines.check_circle Correct
- CThe local backend caps concurrent runs at one per provider, and the fourth engineer is silently queued behind the others.
- DTerraform is refusing to lock the remote state, so applies are colliding until a DynamoDB table is configured.
The local backend stores state per machine with no shared storage or locking, making it unsuitable for team collaboration. Because the local backend persists terraform.tfstate on each user's own disk and provides no remote sharing or locking, parallel applies from different machines each work from a private state file and overwrite one another's results.
Why A is wrong: The local backend stores state as plaintext JSON and performs no encryption, so decryption is not the problem here.
Why B is correct: The local backend keeps state on the local disk with no central copy or locking, so concurrent applies from different machines overwrite each other.
Why C is wrong: No such per-provider concurrency cap exists; the local backend does not coordinate runs across separate machines at all.
Why D is wrong: DynamoDB locking belongs to the S3 backend, not the local backend, so this misattributes the cause to remote infrastructure that is not in use.
lock_openFree sampleTerraform state managementeasy
An engineer wants to keep terraform.tfstate out of the project root and instead write it to a custom path on the same machine, while still using the local backend. Which configuration achieves this?
terraform {
backend "local" {
path = "state/prod.tfstate"
}
}
- AThe shown block is invalid; the local backend does not accept a 'path' argument and always writes to the root.
- BReplace 'backend "local"' with 'cloud' and set an organisation, since only HCP Terraform can relocate state.
- CThe shown block is correct; the local backend's 'path' argument sets where terraform.tfstate is written on disk.check_circle Correct
- DSet the 'TF_STATE_PATH' environment variable instead, because backend blocks cannot configure file locations.
The local backend accepts a path argument to write terraform.tfstate to a custom location on disk. The local backend exposes a 'path' argument whose value replaces the default terraform.tfstate filename and location, letting the state file be stored at any chosen path on the local filesystem.
Why A is wrong: This underestimates the backend; the local backend does support a 'path' argument, so the claim that it is invalid is incorrect.
Why B is wrong: Switching to a 'cloud' block would move state to HCP Terraform entirely, which is not local storage and is not needed to change a local file path.
Why C is correct: The local backend accepts a 'path' argument that overrides the default terraform.tfstate location, so the shown configuration writes state to state/prod.tfstate.
Why D is wrong: There is no 'TF_STATE_PATH' variable that relocates local state, and backend blocks are exactly where the path is configured, so this is wrong.
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.
lock_openFree sampleHCP Terraformmedium
During a plan in HCP Terraform, a team lead wants reviewers to see the projected monthly cost impact of a change before anyone approves the apply, so budget-heavy changes can be caught early. Which capability surfaces this information as part of the run?
- ASentinel policy evaluation, which prints the total monthly bill for the workspace at the end of each successful apply.
- BCost estimation, which produces a projected monthly cost delta for supported resources during the run for reviewers to inspect.check_circle Correct
- CThe private provider registry, which reports the licensing cost of each provider the configuration downloads.
- DRemote state sharing, which aggregates the billing tags exported from every workspace that reads the state.
HCP Terraform cost estimation shows projected monthly cost and the delta for supported resources during a run. After a plan, HCP Terraform's cost estimation calculates a projected monthly cost for supported resources and the change relative to current spend, giving reviewers a budget signal before they approve the apply.
Why A is wrong: Sentinel is a governance engine and can even read cost estimates in a policy, which makes it plausible, but it does not itself generate or display the projected cost figures to reviewers.
Why B is correct: Cost estimation runs after the plan for supported providers and shows the projected monthly cost and the delta versus current spend, exactly the pre-apply visibility the lead wants.
Why C is wrong: The private registry distributes providers and modules and has nothing to do with cloud spend, though pairing cost with providers sounds superficially reasonable.
Why D is wrong: Remote state sharing lets one workspace consume another's outputs, which touches collaboration, but it does not compute or present any cost estimate for a plan.
lock_openFree sampleHCP Terraformmedium
An organisation has several teams sharing one HCP Terraform organisation. The security team should be able to read and comment on runs in a networking workspace but must not be able to queue an apply there. Which mechanism lets an administrator grant exactly this level of access?
- APublishing the networking module to the private registry and marking the security team as consumers of that module version.
- BEnabling remote state sharing from the networking workspace to the security team's own workspace.
- CAssigning the security team read permission on the workspace through team access settings, without granting apply.check_circle Correct
- DWriting a Sentinel policy that allows the security team to approve plans only when no resources are being applied.
HCP Terraform uses teams and RBAC to grant workspace permissions such as read separately from apply. Team access in HCP Terraform maps a team to a permission level on a workspace, so an administrator can grant read to allow viewing and commenting while withholding the apply permission that would let the team queue changes.
Why A is wrong: Private registry publishing controls which modules are discoverable, which sounds like access management, but registry visibility does not govern who may read or apply runs in a workspace.
Why B is wrong: State sharing exposes outputs to another workspace and feels collaboration adjacent, but it grants no run permissions and does not distinguish reading from applying.
Why C is correct: HCP Terraform's team-based RBAC lets an administrator grant a team a specific permission level such as read on a workspace, so the team can view and comment on runs while apply stays withheld.
Why D is wrong: Sentinel governs what a plan may contain, not which users may act on it, so it cannot express a per-team read-only access grant even though it is a governance tool.
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.
lock_openFree sampleInfrastructure as Code (IaC) with Terraformeasy
A colleague proposes to change a production networking rule by editing the Terraform configuration, opening a pull request, and having a teammate approve the diff before it is applied. A manager asks what benefit this workflow adds compared with logging into the console and changing the rule directly. What is the best answer?
- AIt guarantees that the change can never cause an outage once the pull request is merged.
- BIt removes the need to store any state, because pull requests replace Terraform state entirely.
- CIt lets the proposed infrastructure change be reviewed and discussed as a code diff before it is applied.check_circle Correct
- DIt allows the change to be applied without running terraform plan or terraform apply at all.
Code review of infrastructure lets teams inspect and approve changes as diffs before they are applied to real systems. When infrastructure is defined in version-controlled files, a proposed change becomes a diff that others can read, comment on and approve, applying software engineering review practices to infrastructure before any resource is altered.
Why A is wrong: Review reduces mistakes but cannot guarantee zero outages, since an approved change can still be flawed, so this overstates the benefit.
Why B is wrong: Pull requests review the configuration but do not replace state; Terraform still tracks real resources in state, so this is incorrect.
Why C is correct: Expressing infrastructure as code means changes appear as reviewable diffs, so peers can inspect and approve them before they reach production, which is the core advantage over ad hoc console edits.
Why D is wrong: The change must still be applied through Terraform to take effect; review does not bypass plan and apply, so this misdescribes the workflow.
lock_openFree sampleInfrastructure as Code (IaC) with Terraformeasy
An engineer needs to spin up a short-lived testing environment that mirrors production, run automated tests against it, then tear it down, and be able to recreate the very same environment next week. Their Terraform configuration for production is already committed to version control. What is the most appropriate way to gain this repeatable, disposable environment?
terraform apply # stand up the environment
# run test suite
terraform destroy # tear it down afterwards
- AManually recreate the resources in the console each time, keeping notes so the setup can be repeated later.
- BCopy the production state file into the test directory and edit it by hand to point at new resources.
- CTake a one-off snapshot image of the production servers and boot copies of it whenever a test environment is needed.
- DReuse the committed configuration to apply the environment, run tests, then destroy it, applying the same code again when it is next needed.check_circle Correct
Reproducible environments come from applying the same version-controlled configuration on demand and destroying it cleanly when finished. Because the environment is fully described by committed configuration, terraform apply builds it and terraform destroy removes it, and reapplying the same code later recreates an equivalent environment, giving repeatable disposable infrastructure.
Why A is wrong: Manual recreation is slow and drifts between runs, which is the very problem IaC solves, so it defeats the goal of a reproducible environment.
Why B is wrong: Hand-editing state is error prone and unsupported for this purpose; the correct path is to apply configuration, not to manipulate state files directly.
Why C is wrong: A static image captures a point in time and drifts from the source configuration, so it does not give a code-defined, reproducible environment the way reapplying the configuration does.
Why D is correct: Applying the same committed configuration gives a reproducible environment on demand and terraform destroy cleanly removes it, so the identical environment can be stood up again later from the same code.
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.
lock_openFree sampleMaintain infrastructure with Terraformmedium
An engineer needs the current private IP address that Terraform recorded for a single instance so they can paste it into a ticket. They know the resource address is aws_instance.app. Which command prints the attributes of just that one resource from state?
- Aterraform show aws_instance.app
- Bterraform state list aws_instance.app
- Cterraform state show aws_instance.appcheck_circle Correct
- Dterraform output aws_instance.app
Use terraform state show with a resource address to inspect one resource's recorded attributes. terraform state show <address> looks up a single resource in state and prints its stored attribute values, making it the correct tool for reading one instance's details rather than the whole state.
Why A is wrong: terraform show takes an optional plan or state file path as its argument, not a resource address, so passing aws_instance.app here does not select a single resource as intended.
Why B is wrong: terraform state list only filters and prints matching addresses, so it would confirm the resource exists but never display its attribute values such as the private IP.
Why C is correct: terraform state show accepts a single resource address and prints that resource's recorded attributes from state, which is exactly what is needed to read one instance's private IP.
Why D is wrong: terraform output reads named output values, not resource addresses, so it fails unless an output happens to be declared with that exact name, which is not the case here.
lock_openFree sampleMaintain infrastructure with Terraformmedium
A reviewer wants a complete, human-readable dump of every resource currently recorded in state, without providing any resource address and without generating or refreshing a plan. Which command best serves this?
- Aterraform state list
- Bterraform plan -refresh-only
- Cterraform state show
- Dterraform showcheck_circle Correct
Use terraform show without arguments to print the entire current state in human-readable form. Run with no file path, terraform show reads the latest state and renders every tracked resource and its attributes, which is the read-only whole-state view distinct from the address-only terraform state list.
Why A is wrong: terraform state list prints only the resource addresses, so it gives an inventory but not the full human-readable attributes the reviewer asked to see.
Why B is wrong: terraform plan -refresh-only reconciles state with real infrastructure and reports drift, which does extra work and is not a plain read-out of what state currently holds.
Why C is wrong: terraform state show requires a specific resource address and errors without one, so it cannot dump the entire state in a single call.
Why D is correct: terraform show with no file argument prints the current state in a readable form, listing all resources and their attributes without needing an address or a plan.
Examworthy is not affiliated with or endorsed by HashiCorp. All questions are original, blueprint-aligned practice material. We never reproduce live exam items. TF-Associate-004 and related marks belong to their respective owners.