Free Terraform Associate (004) Full-Length Practice Exam: 57 Questions

Try 57 free Terraform Associate (004) questions across the exam domains, with explanations, then continue with full IT Mastery practice.

This free full-length Terraform Associate (004) practice exam includes 57 original IT Mastery questions across the exam domains.

These questions are for self-assessment. They are not official exam questions and do not imply affiliation with the exam sponsor.

Count note: this page uses the full-length practice count maintained in the Mastery exam catalog. Some certification vendors publish total questions, scored questions, duration, or unscored/pretest-item rules differently; always confirm exam-day rules with the sponsor.

Need concept review first? Read the Terraform Associate (004) Cheat Sheet on Tech Exam Lexicon, then return here for timed mocks and full IT Mastery practice.

Open the matching IT Mastery practice page for timed mocks, topic drills, progress tracking, explanations, and full practice.

Try Terraform Associate (004) on Web View full Terraform Associate (004) practice page

Exam snapshot

  • Exam route: Terraform Associate (004)
  • Practice-set question count: 57
  • Time limit: 60 minutes
  • Practice style: mixed-domain diagnostic run with answer explanations

Full-length exam mix

DomainWeight
Infrastructure as Code (IaC) with Terraform8%
Terraform Fundamentals11%
Core Terraform Workflow19%
Terraform Configuration22%
Terraform Modules11%
Terraform State Management11%
Maintain Infrastructure with Terraform8%
HCP Terraform10%

Use this as one diagnostic run. IT Mastery gives you timed mocks, topic drills, analytics, code-reading practice where relevant, and full practice.

Practice questions

Questions 1-25

Question 1

Topic: Terraform State Management

A team updates its Terraform configuration to replace a local backend with a remote backend in the backend block. Before planning any infrastructure changes, which command should they run so Terraform can initialize the new backend and migrate or reconnect state safely?

Options:

  • A. terraform validate

  • B. terraform apply

  • C. terraform plan

  • D. terraform init

Best answer: D

Explanation: When backend configuration changes, Terraform must reinitialize the working directory before other workflow steps. The initialization step prepares the new backend and can prompt to migrate existing state or reconnect to the correct state location safely.

The core concept is backend reinitialization. A Terraform backend determines where state is stored, so changing the backend block is not just a syntax change; Terraform must set up the new backend and confirm how state should be handled.

terraform init is the command that initializes or reinitializes the working directory. When the backend configuration has changed, init detects that change and prompts for the appropriate safe action, such as migrating existing state to the new backend or reconfiguring the workspace to use the new state location.

By contrast, planning and applying are for infrastructure changes after initialization is complete, and validation only checks configuration correctness. The key takeaway is that backend changes require terraform init first.

  • Planning too early fails because terraform plan depends on an initialized backend and does not perform backend migration.
  • Applying too early is wrong because terraform apply makes infrastructure changes, not backend setup or state relocation.
  • Validation only is insufficient because terraform validate checks configuration structure, not backend initialization or state handling.

Question 2

Topic: Terraform Modules

A team wants a reusable child module that callers can customize and then read values from after creation. In Terraform, what defines that module’s public interface to the calling configuration?

Options:

  • A. Resource arguments and local values

  • B. Provider configurations and required providers

  • C. Backend settings and state file entries

  • D. Input variables and output values

Best answer: D

Explanation: A Terraform module is customized through its input variables and consumed through its output values. Together, those two constructs form the module’s interface that the calling configuration uses.

In Terraform, a child module behaves like a reusable component with a defined interface. The caller passes data into the module through input variables, usually in the module block, and reads selected results back through output values, such as IDs or names the module chooses to expose.

This matters because a module’s internal resources, local values, and implementation details should not be the primary way other configurations interact with it. A well-designed module hides its internals and exposes only the inputs callers should set and the outputs callers should consume. That makes the module easier to reuse, version, and maintain.

The key distinction is that variables and outputs are the module boundary; other Terraform constructs may support the module, but they do not define its public interface.

  • Provider confusion: provider settings control how Terraform connects to APIs, not how callers pass values into or read values from a module.
  • Internal implementation: resource arguments and local values are used inside a module, but they are not the caller-facing contract.
  • State mix-up: backend settings and state entries affect where state is stored and tracked, not the module interface exposed to callers.

Question 3

Topic: HCP Terraform

A platform team wants every run in several shared HCP Terraform workspaces evaluated against company rules before an apply can continue. The goal is to enforce shared standards, not just check syntax in one local directory. Which capability best fits this requirement?

Options:

  • A. terraform fmt

  • B. HCP Terraform policy checks

  • C. terraform validate

  • D. HCP Terraform variable sets

Best answer: B

Explanation: HCP Terraform policy checks are meant for governance across teams and workspaces. They evaluate runs against centralized rules before apply proceeds. Local CLI commands like terraform validate and terraform fmt only check or format local configuration, and variable sets only share values.

The core concept is the difference between local CLI functionality and HCP Terraform governance features. If a team needs centralized control over whether runs can proceed based on company standards, that is a governance requirement, and HCP Terraform policy checks are designed for it.

Policy checks evaluate runs against defined rules before apply. That makes them suitable for organization-wide standards such as required tags, blocked resource patterns, or other compliance controls across shared workspaces. By contrast, terraform validate checks whether configuration is syntactically valid and internally consistent, and terraform fmt only rewrites files into canonical formatting. Variable sets help share common input values, but they do not enforce rules.

When the need is team control or shared standards, choose an HCP Terraform governance feature instead of a local CLI command.

  • Syntax only: the option using terraform validate checks configuration correctness, not centralized policy enforcement.
  • Shared values: the option using variable sets helps standardize inputs across workspaces, but it does not block runs based on rules.
  • Formatting only: the option using terraform fmt improves style consistency in files, not governance or approvals.

Question 4

Topic: HCP Terraform

In HCP Terraform, which capability is used to evaluate a run against organizational rules before the run is allowed to apply infrastructure changes?

Options:

  • A. Policy checks

  • B. Private registry

  • C. Projects

  • D. Drift detection

Best answer: A

Explanation: Policy checks are the HCP Terraform feature that enforces governance during a run. They evaluate the run against defined rules and can stop an apply when those rules are not satisfied.

In HCP Terraform, policy checks are used for governance enforcement during the run workflow. They inspect run data, such as the planned changes, against organizational policies and can prevent an apply from continuing when the rules are violated. That makes them the correct choice when the goal is to gate infrastructure changes before they are applied.

The other listed features support governance in different ways. Drift detection helps identify out-of-band changes, private registry helps teams share approved modules, and projects help organize workspaces. Those are useful governance capabilities, but they do not directly evaluate a run and block or allow the apply step. The key distinction is enforcement during the run versus monitoring, reuse, or organization.

  • Drift detection finds changes made outside Terraform, but it does not enforce rules before apply.
  • Private registry supports sharing approved modules, not evaluating run-time policy compliance.
  • Projects group and organize workspaces, but they do not inspect plans or gate applies.

Question 5

Topic: Terraform Configuration

A module variable must accept a value with fixed, named attributes: name as a string, instance_count as a number, and enable_monitoring as a bool. The attribute names are known in advance, and each attribute can have a different type. Which Terraform type constraint is most appropriate?

Options:

  • A. object({ name = string, instance_count = number, enable_monitoring = bool })

  • B. set(any)

  • C. tuple([string, number, bool])

  • D. map(string)

Best answer: A

Explanation: Use an object when a value has known attribute names and those attributes can have different types. This matches a structured input like name, instance_count, and enable_monitoring better than positional or same-type collections.

Terraform complex types are chosen by data shape. Use object when the input is a structured value with specific attribute names, and those attributes may have different types. Here, the value has three known fields: a string, a number, and a boolean.

  • map(...) is for string keys whose values are all the same type.
  • tuple([...]) allows mixed types, but elements are identified by position rather than by name.
  • set(...) is an unordered collection of unique elements, not a record with fixed fields.

The deciding factor is named attributes with mixed value types, which is exactly what object is for.

  • map(string) fails because all map values must be strings, but the input includes a number and a boolean.
  • tuple([string, number, bool]) supports mixed types, but it uses positional elements instead of named attributes.
  • set(any) represents an unordered collection of unique elements, not a structured value with predefined fields.

Question 6

Topic: Terraform State Management

A user runs terraform apply and receives an error that Terraform cannot acquire the state lock because another operation is already holding it. Which Terraform concept best explains this situation?

Options:

  • A. State locking coordinates shared access to state.

  • B. The configuration failed Terraform validation.

  • C. The dependency lock file has invalid provider selections.

  • D. Drift has been detected between state and infrastructure.

Best answer: A

Explanation: A state lock error means Terraform is preventing concurrent operations from changing the same state at the same time. That is a shared-state coordination issue, not evidence that the HCL configuration itself is invalid.

Terraform state is a shared record of managed infrastructure, so concurrent writes can corrupt or desynchronize it. State locking exists to prevent two users or runs from updating the same state file at once. When Terraform waits for a lock or fails to acquire one, the problem is usually that another operation is already using that state, or a previous lock was not released cleanly.

This is different from configuration problems, which are identified by commands like terraform validate or by plan/apply errors about arguments, references, or provider behavior. It is also different from drift, which means the real infrastructure no longer matches the recorded state. The key takeaway is that a lock-related message points first to state coordination and backend locking behavior.

  • The option about the dependency lock file is about provider version selections, not shared access to Terraform state.
  • The option about drift is about differences between real infrastructure and recorded state, not an active lock.
  • The option about failed validation would indicate invalid configuration structure or references, not a concurrent state operation.

Question 7

Topic: Terraform Configuration

A reusable module has an input variable named environment. The module author wants Terraform to stop with a clear custom message if a caller passes anything other than dev, test, or prod. Which Terraform feature should the author use?

Options:

  • A. A check block

  • B. A precondition on a resource

  • C. Variable validation on the input variable

  • D. A postcondition on a resource

Best answer: C

Explanation: Use variable validation when the problem is an invalid caller-supplied input. It lets Terraform fail early on a variable value and explain exactly which values are allowed.

Variable validation is the right choice when Terraform needs to explain why an input value is unacceptable. You attach the rule to the variable block, and Terraform can stop with a custom error message if the caller provides a disallowed value such as anything outside dev, test, or prod.

  • Preconditions validate assumptions before Terraform uses a resource, data source, or output.
  • Postconditions validate the result after Terraform evaluates a resource, data source, or output.
  • check blocks are for broader infrastructure assertions, not the primary tool for rejecting bad input variables.

If the issue begins with what the user typed into an input variable, choose variable validation.

  • The option using a precondition is tempting, but preconditions are for assumptions about resources, data sources, or outputs rather than direct input-variable rules.
  • The option using a postcondition is too late because postconditions verify a result after evaluation, not the caller’s original input.
  • The option using a check block does not fit because checks are meant for broader assertions about infrastructure behavior, not standard input rejection.

Question 8

Topic: Terraform Fundamentals

What is the main purpose of a Terraform provider alias?

Options:

  • A. Lock a provider to a specific version for reproducible runs

  • B. Define additional configurations of the same provider for different accounts, regions, or endpoints

  • C. Store separate state files for different environments

  • D. Pass values between parent and child modules

Best answer: B

Explanation: A provider alias is used when one provider configuration is not enough in a single Terraform configuration. It allows the same provider to be configured multiple ways, such as for different accounts, regions, or API endpoints.

Terraform uses provider configurations to connect to external platforms and APIs. When you need the same provider to behave differently in one configuration—such as using different credentials, regions, or service endpoints—you define an additional provider configuration with an alias. Resources can then select that aliased provider, and modules can be passed the correct provider configuration from the root module.

  • A default provider configuration is used unless another one is specified.
  • An aliased provider is an extra configuration of the same provider.
  • Common reasons include multiple accounts, multiple regions, or alternate endpoints.

This is different from separating state, passing module values, or pinning provider versions, which each solve different Terraform problems.

  • Separate state files are handled by backend and state strategy choices, not by provider aliases.
  • Passing values between modules uses input variables and outputs, not provider configuration.
  • Version pinning is done with required_providers and the dependency lock file, not with aliases.

Question 9

Topic: Terraform Configuration

A Terraform configuration uses a data source to find the latest machine image. The team wants Terraform to stop with a custom message if the returned image does not have the required approved = true tag. Which Terraform construct is the best fit?

Options:

  • A. Postcondition

  • B. Variable validation

  • C. Precondition

  • D. Check block

Best answer: A

Explanation: Use a postcondition when the unacceptable value is the result returned by a resource or data source. Here, Terraform must inspect the image after the lookup completes and fail with a clear message if the result is not approved.

Terraform custom conditions apply at different points in evaluation. Variable validation is only for caller-supplied input variables. Preconditions verify assumptions before Terraform fully evaluates a resource, data source, or output. Postconditions verify the final value returned by a resource or data source, which makes them the right choice when a lookup succeeds but the result is still unacceptable. In this scenario, the required tag exists on the data source result, so Terraform must check the returned object and reject it if approved is not true. A check block is better for broader validation and health assertions, not for making this specific lookup result unacceptable. The key distinction is validating a returned result rather than an input.

  • Variable validation only works on input variables, so it cannot inspect a value returned from a data source.
  • Precondition fits assumptions Terraform can verify before evaluation, not acceptance criteria for the returned image itself.
  • Check block is for broader validation and assertions, not the main object-level mechanism for rejecting a specific data source result.

Question 10

Topic: Terraform State Management

A team uses one shared Terraform state for a production environment. Multiple engineers or automated runs might start terraform apply against that same state around the same time. Why is state locking especially important in this workflow?

Options:

  • A. It automatically splits the state into separate files per resource.

  • B. It stores provider plugins in the backend for consistent installs.

  • C. It guarantees the real infrastructure always matches the configuration.

  • D. It ensures only one operation can update the shared state at a time.

Best answer: D

Explanation: State locking protects Terraform state when multiple users or runs target the same deployment. It prevents simultaneous state updates, which helps avoid conflicting writes, failed runs, and corrupted shared state.

State locking is a safeguard for shared Terraform state during operations that may change it. In a collaborative workflow, two people or an automated run and a human operator could both start work from the same current state and then try to write back changes. Without locking, those concurrent updates can conflict and leave the state inaccurate or inconsistent. A backend that supports locking lets Terraform allow one state-changing operation at a time, preserving the integrity of the shared source of truth. Locking does not manage plugins, reorganize state files, or guarantee that infrastructure never drifts; it specifically protects state during concurrent access.

  • The option about storing provider plugins confuses dependency installation with state protection.
  • The option about splitting state per resource describes state design, not locking behavior.
  • The option about guaranteeing infrastructure always matches configuration overstates what Terraform can ensure; locking only controls concurrent state access.

Question 11

Topic: Terraform Modules

A team has separate dev, stage, and prod root configurations in one repository. Each contains nearly identical Terraform blocks for a standard app stack, with only a few names and sizes different. They want to update that pattern in one place, keep environments consistent, and still review plans per environment before apply. What is the best next action?

Options:

  • A. Store the differing values in .tfvars files, but keep separate copies of the resource blocks in each environment directory.

  • B. Extract the shared resources into a child module, pass environment-specific values as inputs, and call it from each root configuration.

  • C. Move all environments into one HCP Terraform workspace so a single configuration manages every environment together.

  • D. Replace the repeated resources with data sources so each environment reads the same infrastructure definition.

Best answer: B

Explanation: Terraform modules are the standard way to reuse and standardize repeated infrastructure patterns. A child module lets the team keep one shared definition of the app stack while passing different values for each environment and preserving separate plan reviews.

When the goal is reuse, consistency, and cleaner separation of repeated infrastructure, Terraform modules are the best fit. The repeated app stack should be moved into a child module, and each environment root configuration should call that module with its own input values such as names, sizes, or CIDR ranges.

This approach gives the team:

  • one place to maintain the shared pattern
  • consistent structure across dev, stage, and prod
  • separate plans and state per environment if they keep separate root configurations

Using variable files alone does not remove duplicated resource blocks. Combining all environments into one workspace reduces isolation, and data sources are for reading existing infrastructure, not defining reusable managed patterns. The key takeaway is that modules package repeated infrastructure logic for safe, consistent reuse.

  • Keeping copied resource blocks with .tfvars changes input values but does not remove duplication.
  • Managing all environments in one workspace reduces environment separation and can complicate safe review.
  • Using data sources confuses reading existing infrastructure with defining reusable infrastructure to create and manage.

Question 12

Topic: Maintain Infrastructure with Terraform

Which statement best describes the Terraform environment variable TF_LOG?

Options:

  • A. It supplies input variable values to Terraform.

  • B. It forces Terraform to reinitialize providers and modules.

  • C. It selects the active Terraform workspace.

  • D. It increases Terraform diagnostic log verbosity.

Best answer: D

Explanation: TF_LOG controls Terraform’s diagnostic logging level. When you set it, Terraform prints more detailed internal messages, which helps troubleshoot issues during commands such as plan or apply.

Terraform supports environment-driven diagnostic logging through TF_LOG. Setting this variable to a level such as INFO, DEBUG, or TRACE increases the amount of detail Terraform emits while it runs. That extra output is useful when investigating provider behavior, configuration issues, or unexpected command results.

TF_LOG is specifically about troubleshooting visibility. It does not choose a workspace, pass input variables, or reinitialize the working directory. Those are separate Terraform features and workflows.

The key idea is simple: if you need more Terraform diagnostic detail, TF_LOG is the environment variable designed for that purpose.

  • The workspace option describes selecting state context, which is separate from logging.
  • The input variable option matches the TF_VAR_ pattern, not diagnostic output control.
  • The reinitialize option refers to terraform init, which prepares the working directory rather than increasing log detail.

Question 13

Topic: Terraform Configuration

A team uses a VCS-driven HCP Terraform workspace. An engineer commits this Terraform excerpt to the repo:

variable "db_password" {
  type      = string
  sensitive = true
  default   = "P@ssw0rd123!"
}

resource "aws_db_instance" "app" {
  password = var.db_password
}

What is the best next step?

Options:

  • A. Keep the default because sensitive = true prevents the password from reaching state.

  • B. Keep the code and switch the workspace to a remote backend.

  • C. Remove the default and supply the password from HCP Terraform sensitive variables or Vault.

  • D. Add .tfvars files to .gitignore and keep the current variable default.

Best answer: C

Explanation: This configuration still hardcodes a secret, which is a Terraform anti-pattern. sensitive = true only redacts display output; it does not make a hardcoded default safe in source files, Git history, or state.

Best practice is to keep secrets out of Terraform configuration files entirely. In this excerpt, the password is embedded in the variable default, so anyone with access to the code repository or its history can retrieve it. Marking the variable as sensitive helps hide the value in some Terraform output, but it does not remove the secret from the .tf file and does not guarantee the value stays out of state when a resource uses it.

Safer patterns include:

  • setting the value as an HCP Terraform sensitive variable
  • supplying it at runtime from a secure external source
  • retrieving it from a secret manager such as Vault

A remote backend improves state storage and collaboration, but it does not fix a secret that is already hardcoded in configuration. The key takeaway is that redaction is not the same as secret management.

  • Display redaction only: marking a variable as sensitive hides some output, but it does not protect a hardcoded default in code or history.
  • Remote backend confusion: moving state to a remote backend helps with shared state and locking, not with secrets already committed to configuration.
  • Wrong file focus: ignoring .tfvars files does nothing when the secret is embedded directly in the variable block.

Question 14

Topic: Core Terraform Workflow

A team needs Terraform to stop tracking one existing instance, but the cloud instance must remain running. In the current workspace, they run:

$ terraform state rm aws_instance.web
Removed aws_instance.web
Successfully removed 1 resource instance(s).

What is the best interpretation of this result?

Options:

  • A. Terraform marked the instance to be destroyed on the next terraform apply.

  • B. Terraform forgot the instance in state; it still exists but is unmanaged.

  • C. Terraform automatically moved the instance to another workspace.

  • D. Terraform destroyed the instance and then updated the state.

Best answer: B

Explanation: The excerpt shows terraform state rm, which removes a resource binding from Terraform state only. That stops Terraform from tracking the object, but it does not delete the real infrastructure.

Terraform state stores the mapping between a resource address in configuration and the real object that exists in the provider. The terraform state rm command removes that mapping from state, so Terraform “forgets” the object. The live resource continues to exist unless you separately destroy it outside this command.

If the resource block still remains in configuration, a later plan may propose creating a new object because Terraform no longer has a state entry for the existing one. By contrast, destroying infrastructure requires a destroy action, such as terraform destroy or a plan/apply that shows a delete change.

The key point is that removing state bindings is not the same as deleting real infrastructure.

  • Destroyed it is wrong because the excerpt shows a state command, not a destroy plan or apply.
  • Destroy on next apply is wrong because removing state does not schedule deletion; it only removes tracking.
  • Moved workspaces is wrong because moving management elsewhere requires an explicit migration step, not state rm.

Question 15

Topic: Maintain Infrastructure with Terraform

A teammate enabled verbose logging to troubleshoot remote state initialization and wants to paste the full log into an incident ticket that many contractors can view. Based on this excerpt, what is the best next step?

$ TF_LOG=TRACE terraform init
2026-04-07T10:14:32Z [TRACE] Meta.Backend: built configuration for "http"
2026-04-07T10:14:32Z [DEBUG] GET https://state.example.internal/prod/terraform.tfstate
2026-04-07T10:14:32Z [DEBUG] Authorization: Bearer eyJhbGciOi...
2026-04-07T10:14:32Z [TRACE] state path: prod/networking/terraform.tfstate

Options:

  • A. Replace the token and share the remaining trace broadly.

  • B. Commit the trace with the configuration for team review.

  • C. Share only a redacted excerpt through a restricted channel.

  • D. Post the full trace because Terraform masks verbose logs.

Best answer: C

Explanation: The excerpt already shows a bearer token and a state path, so the log must be treated as sensitive. Verbose Terraform logs can reveal credentials, backend details, and other secret-bearing data, so the safest action is to redact and limit who can see it.

TF_LOG=TRACE is useful for troubleshooting, but detailed Terraform logs can contain backend URLs, authentication headers, state object locations, request details, and other sensitive operational data. In this excerpt, both a bearer token and a state path are visible, so pasting the raw log into a widely visible ticket creates unnecessary exposure.

A safer approach is to:

  • keep only the few lines needed for debugging
  • redact tokens, secrets, and internal state identifiers
  • share the excerpt only with the people who need it

Marking variables or outputs as sensitive helps reduce normal CLI display, but it does not guarantee every verbose log line is sanitized. The key takeaway is to handle detailed Terraform logs like any other secret-bearing artifact.

  • The option claiming verbose logs are automatically masked fails because TRACE and DEBUG output can still include tokens and backend request data.
  • The option suggesting only token replacement is insufficient because the remaining trace still exposes internal state locations and backend details.
  • The option suggesting committing the trace to version control increases risk by making sensitive troubleshooting data persistent and broadly accessible.

Question 16

Topic: Terraform Fundamentals

Which Terraform block is used to configure provider-specific settings such as region, API endpoint, or authentication-related inputs?

Options:

  • A. provider block

  • B. backend block

  • C. terraform block

  • D. resource block

Best answer: A

Explanation: Terraform uses the provider block to define how it should connect to and interact with a specific platform or service. Settings like region, custom endpoints, and authentication-related inputs belong there, not in blocks for state, version requirements, or managed objects.

Terraform separates provider selection from provider configuration. The terraform block can declare required providers and version constraints, but the provider block is where you set the provider-specific values Terraform needs in order to talk to that platform, such as region, endpoint, or authentication inputs. Resources then rely on that provider configuration when Terraform plans and applies changes.

provider "aws" {
  region = "us-east-1"
}

A useful memory aid is: the provider block tells Terraform how to connect, while a resource block tells Terraform what to manage.

  • The terraform block is for settings such as required_providers and backends, not provider runtime configuration.
  • The backend block controls where state is stored and locked, not how Terraform connects to a cloud or service API.
  • The resource block defines an infrastructure object to manage, not shared provider-wide settings.

Question 17

Topic: Terraform State Management

Which statement best reflects Terraform’s recommended practice when a resource address changes or an object should no longer be managed in state?

Options:

  • A. Edit the .tfstate file directly to change the binding.

  • B. Use terraform import to replace any old mapping.

  • C. Run terraform plan to rewrite the stored address.

  • D. Use supported moved/removed workflows instead of manual state edits.

Best answer: D

Explanation: Terraform state should be changed through supported mechanisms whenever possible. For moved or no-longer-managed objects, Terraform expects explicit workflows such as moved or removed handling, not hand-edited state JSON.

Terraform state records the mapping between a resource address in configuration and a real infrastructure object. When that mapping changes because a resource was renamed, moved into a module, or intentionally removed from management, the recommended approach is to use supported Terraform mechanisms such as moved and removed handling, or appropriate terraform state commands when needed. These methods let Terraform understand the transition and reduce the risk of corrupting state, recreating resources unexpectedly, or planning unintended destroys. Directly editing the state file is an ad hoc and risky approach. A normal plan or import does not automatically or correctly replace explicit state-mapping changes.

  • Direct state edits are risky because manual JSON changes can corrupt bindings or lead to unintended actions.
  • Import confusion fails because terraform import is for bringing existing infrastructure under Terraform management, not for normal moved or removed mappings.
  • Plan confusion fails because terraform plan shows proposed changes; it does not automatically rewrite resource addresses in state.

Question 18

Topic: HCP Terraform

A platform team manages production changes in HCP Terraform. They want runs executed centrally, a person to approve production applies, and shared guardrails across teams.

Exhibit:

Workspace: app-prod
Execution mode: Remote
Run trigger: VCS-driven
Apply method: Manual apply
Policy checks: Enabled

Which interpretation is most accurate?

Options:

  • A. A remote backend alone provides approvals and organization-wide policy checks.

  • B. HCP Terraform provides remote runs, policy checks, and manual approval gates.

  • C. Local CLI workflows provide the same centralized approvals and governance controls.

  • D. Reusable modules alone enforce approval gates across team workspaces.

Best answer: B

Explanation: The exhibit describes HCP Terraform collaboration and governance features, not just core local Terraform CLI behavior. Remote execution, VCS-driven runs, policy checks, and manual apply together support centralized control, shared guardrails, and human approval before infrastructure changes are applied.

HCP Terraform adds team-oriented workflow controls that the local CLI does not provide by itself. In the exhibit, Execution mode: Remote means runs occur in HCP Terraform, Run trigger: VCS-driven ties runs to version-controlled changes, Policy checks: Enabled indicates governance rules can evaluate the run, and Apply method: Manual apply requires a person to approve the apply step. Together, these features address collaboration, approvals, and shared standards in a centralized workflow.

Local commands such as terraform plan, terraform apply, terraform validate, and terraform fmt are still useful, but they do not by themselves create an HCP-managed approval gate or organization-wide policy enforcement. A remote backend or reusable module can help with state or reuse, but neither replaces HCP Terraform governance features.

  • Local CLI only can preview or apply changes, but it does not create centralized HCP approval gates or policy checks.
  • Remote backend only helps store and coordinate state; it is not the same as HCP Terraform governance controls.
  • Modules for reuse standardize configuration structure, but they do not by themselves require human approval before apply.

Question 19

Topic: Terraform Modules

A cloud engineer reviews this configuration:

module "network" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"
  name    = "prod-vpc"
}

What is the best interpretation of the source argument?

Options:

  • A. It tells Terraform which outputs the module will return.

  • B. It tells Terraform which provider plugin version to install.

  • C. It tells Terraform where to store state for this module.

  • D. It tells Terraform where to obtain the reusable module code.

Best answer: D

Explanation: In a module block, source identifies the module location. In this example, the value is a registry address, so Terraform knows where to download the reusable module code.

The core concept is that source in a module block tells Terraform where the reusable module code lives. Terraform uses that location during terraform init to install or read the module. A source can point to the public registry, a private registry, a VCS repository, an archive, or a local path. In the snippet, terraform-aws-modules/vpc/aws is a registry-style source, while version limits which published module version to use. State storage is configured separately with a backend, and provider installation is handled through provider requirements. The key takeaway is that source answers “where is the module code?” rather than anything about state, providers, or outputs.

  • Provider confusion: provider plugin versions are controlled by required_providers and provider configuration, not by a module source.
  • State confusion: state location is configured with a backend for the working directory, not inside a module block.
  • Output confusion: outputs are declared inside the module with output blocks; source only tells Terraform where that module comes from.

Question 20

Topic: Terraform Modules

A team reuses a registry module across several environments:

module "network" {
  source  = "appcorp/network/aws"
  version = "~> 2.4.0"
}

What is the main benefit of including the version argument in this module block?

Options:

  • A. It pins the provider plugin versions used by the module.

  • B. It keeps module selection predictable and reduces unexpected breaking changes.

  • C. It automatically upgrades the module to any future major release.

  • D. It stores the module’s resources in a separate state file.

Best answer: B

Explanation: Module version constraints tell Terraform which registry module releases are acceptable. That keeps runs more predictable across environments and helps prevent a newer module release from introducing breaking changes unexpectedly. Teams can then upgrade on purpose instead of by surprise.

In a module block, the version argument constrains which releases Terraform can install from a registry source. This matters for reused modules because teams depend on stable inputs, outputs, and behavior across environments. Without a constraint, a fresh working directory or an intentional upgrade can pull a newer module release, including one with breaking changes. By setting an allowed version range, teams make runs more predictable and choose when to test and adopt newer module versions.

Version constraints control acceptable module releases; they do not pin provider plugins or change how Terraform state is stored.

  • Provider confusion fails because module version constraints do not lock provider plugin versions; provider version constraints handle that.
  • Separate state fails because using a module does not create a separate state file for that module’s resources.
  • Automatic major upgrades fails because version constraints are used to limit acceptable releases, not to allow all future breaking versions.

Question 21

Topic: Core Terraform Workflow

Which situation is the most appropriate use of terraform destroy?

Options:

  • A. Reconciling drift after a manual change to a managed resource

  • B. Repairing state after a resource was removed from state by mistake

  • C. Re-downloading providers after changing a provider version

  • D. Removing a temporary development environment that is no longer needed

Best answer: D

Explanation: Use terraform destroy when the goal is to intentionally remove Terraform-managed infrastructure, such as a disposable sandbox or test environment. It is a teardown command, not a tool for drift correction, state repair, or provider installation.

The key concept is intent. terraform destroy creates and applies a plan to delete the Terraform-managed resources in the current configuration scope, so it fits environments that are meant to be temporary. Common examples include short-lived development, test, or demo stacks that should be torn down when work is finished.

If resources have drifted because someone changed them manually, the usual workflow is to run terraform plan and then terraform apply to bring real infrastructure back in line with configuration. If the state is wrong or incomplete, use safer state workflows such as import, moved blocks, or careful terraform state commands. Provider installation or upgrades are handled by terraform init.

A good rule is: destroy is for intentional deletion, not correction or repair.

  • The option about manual drift is a reconciliation task; review the plan and apply the declared configuration instead of deleting everything.
  • The option about repairing state confuses infrastructure teardown with state management; state issues need import or other state-safe fixes.
  • The option about re-downloading providers refers to initialization work, which is handled by terraform init, not by removing resources.

Question 22

Topic: Infrastructure as Code (IaC) with Terraform

A platform team uses one HCP Terraform workspace for a root module. Exhibit:

Terraform will perform the following actions:

  # aws_s3_bucket.logs will be created
  + resource "aws_s3_bucket" "logs"

  # vsphere_virtual_machine.app will be created
  + resource "vsphere_virtual_machine" "app"

Plan: 2 to add, 0 to change, 0 to destroy.

What is the best interpretation of this plan?

Options:

  • A. It requires separate state files for cloud and on-prem resources.

  • B. It means the vSphere object can only be a data source.

  • C. It shows a hybrid workflow using multiple providers in one configuration.

  • D. It is invalid because one workspace can use only one provider.

Best answer: C

Explanation: The plan shows Terraform preparing changes for both AWS and vSphere from the same workspace. That is a hybrid workflow: Terraform can manage cloud and on-premises resources together when the configuration uses the appropriate providers.

Terraform is provider-agnostic. In this plan, one run includes an AWS resource and a vSphere resource, so the same Terraform configuration estate is managing both cloud and on-premises infrastructure. That is a classic hybrid workflow.

Terraform does not limit a workspace or root module to a single provider. If the required providers are available and configured, one plan can include resources from different platforms and services, and Terraform can track them together in state. Teams may still choose separate states or workspaces for organizational or lifecycle reasons, but different platforms alone do not require that split.

The key signal is that both resource types appear in the same plan output.

  • One-provider limit is incorrect because a single Terraform run can include resources from multiple providers.
  • Data source confusion is incorrect because the exhibit shows a managed resource, not a read-only data source.
  • Mandatory split is incorrect because separate state files are a design choice, not a requirement just because the estate is hybrid.

Question 23

Topic: Terraform State Management

Which statement best describes Terraform’s local backend?

Options:

  • A. It stores state locally but automatically coordinates safe sharing across multiple operators.

  • B. It stores state on local disk, which is simple for solo or disposable work but weak for centralized team control.

  • C. It stores state in HCP Terraform, which centralizes runs, policy checks, and collaboration.

  • D. It avoids state files entirely by reading infrastructure directly from providers each run.

Best answer: B

Explanation: The local backend writes Terraform state to local disk. That makes it easy to start with and suitable for one person or short-lived environments, but it does not provide the centralized storage and collaboration model teams usually need.

A Terraform backend decides where state is stored and accessed. The local backend is the default and keeps the state file on the machine running Terraform, typically in terraform.tfstate. That simplicity works well for learning, one-person projects, or disposable environments because no separate service is required.

Its main limitation appears when multiple people need to work with the same infrastructure. Local state is not centrally managed, so sharing, coordination, and governance are harder than with a remote backend or an HCP Terraform workspace. Terraform still depends on state either way; the local backend does not remove state or turn it into a managed service.

The key takeaway is simple setup for solo work, but limited collaboration and centralized control.

  • The HCP Terraform choice describes a managed remote workflow, not the local backend.
  • The automatic team-coordination choice overstates local state; a file on one machine is not centralized collaboration.
  • The no-state-file choice is incorrect because Terraform uses state to track infrastructure, including with the local backend.

Question 24

Topic: Terraform Fundamentals

A root module defines two AWS provider configurations: the default targets us-east-1, and an aliased provider aws.dr targets us-west-2. A child module must create all of its resources in us-west-2.

provider "aws" {
  region = "us-east-1"
}

provider "aws" {
  alias  = "dr"
  region = "us-west-2"
}

module "disaster_recovery" {
  source = "./modules/dr"
}

Which change is required so the child module uses the non-default provider configuration?

Options:

  • A. Add provider = aws.dr to the module block.

  • B. Run terraform apply -target=module.disaster_recovery.

  • C. Change the default AWS provider region to us-west-2.

  • D. Add providers = { aws = aws.dr } to the module block.

Best answer: D

Explanation: The child module must be explicitly mapped to the aliased provider because the default AWS provider points to the wrong region. In Terraform, a module uses a non-default provider configuration only when the parent passes it through the module block’s providers argument.

Terraform uses the default provider configuration unless you explicitly select another one. In this scenario, the default aws provider points to us-east-1, so the child module would otherwise plan its resources there instead of us-west-2.

  • Use provider = aws.dr for an individual resource in the same module.
  • Use providers = { aws = aws.dr } to pass an aliased provider into a child module.
  • Keep the default provider unchanged when only one module needs the alternate region.

Commands such as init or apply -target do not change which provider configuration a module is associated with.

  • Wrong argument The option using provider = aws.dr fails because module blocks use providers, not the resource-level provider meta-argument.
  • Too broad Changing the default provider region would affect every AWS resource that still uses the default configuration.
  • Wrong tool Targeting the module during apply changes graph selection, not the provider configuration bound to that module.

Question 25

Topic: Infrastructure as Code (IaC) with Terraform

A platform team wants to hide provider-specific resource details behind a reusable building block so the same Terraform workflow can be used for AWS, Azure, or on-premises deployments. Which Terraform concept is designed for that purpose?

Options:

  • A. Module

  • B. Backend

  • C. Workspace

  • D. Provider

Best answer: A

Explanation: A module is Terraform’s reuse mechanism for infrastructure code. It lets teams package a pattern once and call it repeatedly with different inputs, which supports service-agnostic automation across clouds and hybrid environments.

Modules are Terraform’s primary way to create reusable infrastructure automation patterns. A module groups resources, variables, and outputs into a single building block that can be called multiple times. In a multi-cloud or hybrid scenario, that matters because the goal is to reuse the Terraform pattern even when provider-specific resources differ underneath. A root module can call child modules and pass different values or provider settings for different targets.

Providers define how Terraform interacts with a platform, backends determine where state is stored, and workspaces separate state instances. Those are important workflow concepts, but they do not package reusable infrastructure logic. The key takeaway is that reusable automation patterns belong in modules.

  • Provider confusion: a provider enables Terraform to manage a platform’s resources, but it does not bundle reusable infrastructure logic.
  • Backend confusion: a backend controls state storage and locking, not how a standard deployment pattern is packaged.
  • Workspace confusion: a workspace separates state for different instances, such as environments, rather than defining reusable infrastructure code.

Questions 26-50

Question 26

Topic: Core Terraform Workflow

After the working directory has already been initialized, which Terraform command is intended to catch configuration errors early in local development or CI before you create an execution plan?

Options:

  • A. terraform init

  • B. terraform validate

  • C. terraform fmt

  • D. terraform plan

Best answer: B

Explanation: terraform validate is the dedicated early check for Terraform configuration correctness. It verifies syntax and internal consistency in an initialized working directory, making it a common step in local development and CI before later workflow commands.

The key concept is command purpose. terraform validate is used to verify that Terraform configuration files are syntactically valid and internally consistent, such as correct block structure, valid references, and acceptable argument placement. It is designed as a fast quality check before planning or applying changes, so it fits naturally into local development and CI pipelines.

In a typical workflow:

  • terraform init prepares the directory
  • terraform validate checks configuration correctness
  • terraform plan previews proposed changes

The closest distractor is terraform plan, because it can reveal problems, but its main job is to generate an execution plan rather than serve as the primary early validation step.

  • terraform fmt is for code formatting, not for checking whether the configuration is logically valid.
  • terraform plan can surface issues, but it is primarily for previewing infrastructure changes.
  • terraform init prepares the working directory by installing providers and modules; it does not validate configuration correctness.

Question 27

Topic: Core Terraform Workflow

A team uses a VCS-driven HCP Terraform workspace for production. A pull request updates network settings, and another engineer must review any adds, changes, replacements, or destroys before approval. The review must use the same workspace variables and versions as the real run. What is the best next action?

Options:

  • A. Run terraform plan locally and use that output for approval.

  • B. Merge the change and let terraform apply reveal the actions.

  • C. Refactor the network code into a shared module before reviewing.

  • D. Review the workspace run’s execution plan, then approve apply if expected.

Best answer: D

Explanation: The execution plan is the Terraform stage used to review proposed changes before apply. In a VCS-driven HCP Terraform workspace, the team should inspect the run’s plan because it reflects the workspace’s actual variables and versions before anyone approves infrastructure changes.

Terraform separates planning from applying. The execution plan compares the current configuration, state, and real infrastructure, then lists the proposed actions: create, update in place, replace, or destroy. That makes it the correct stage for safe review before any infrastructure is modified.

In HCP Terraform, a VCS-triggered run generates this plan in the workspace so collaborators can review the exact output tied to that workspace’s variables, provider selections, and approval flow. A local plan can help an individual check syntax or expected behavior, but it is not the shared approval artifact for the remote run. apply performs the changes, and module refactoring improves reuse rather than change review.

The key workflow is to review the execution plan first, then approve or apply only if the proposed actions are expected.

  • Local plan mismatch can differ from the remote workspace context and is not the shared approval artifact for the HCP Terraform run.
  • Applying first changes infrastructure before the team reviews the proposed diff.
  • Module refactoring can improve reuse, but it does not show the pending actions for this change.

Question 28

Topic: HCP Terraform

A team uses a VCS-driven HCP Terraform workspace. During a run, they see this note:

HCP Terraform run summary
Project: production-apps
Workspace: web-prod
Execution mode: Remote
Plan: Finished
Policy checks: 2 passed, 1 failed
Apply status: Blocked

Which interpretation is best?

Options:

  • A. A policy set evaluated the run and blocked apply until the violation is resolved.

  • B. The project grouping feature requires manual approval before any run can proceed.

  • C. Drift detection found unmanaged infrastructure changes and automatically canceled the plan.

  • D. A private registry module failed publishing, so the workspace cannot continue the run.

Best answer: A

Explanation: The exhibit explicitly shows failed policy checks and a blocked apply. In HCP Terraform, that means governance rules were evaluated during the run and at least one policy failed, so the run cannot continue to apply.

This exhibit points to policy enforcement. In HCP Terraform, policy checks evaluate a run against governance rules, and a failed check can block the apply step.

The other governance-oriented features in the objective do different jobs:

  • Projects organize related workspaces.
  • Drift detection identifies out-of-band infrastructure changes.
  • Private registry shares approved modules and providers internally.

The deciding evidence is Policy checks: 2 passed, 1 failed together with Apply status: Blocked. That combination means the run completed planning, then a governance policy stopped it from moving forward. The key takeaway is that policy checks control whether a run is allowed to continue; the other features organize, share, or observe infrastructure.

  • Drift confusion fails because the exhibit shows failed policy checks, not out-of-band changes between state and real infrastructure.
  • Registry confusion fails because nothing in the note indicates a module publishing or retrieval problem from a private registry.
  • Project confusion fails because projects group workspaces, but project membership alone does not block apply.

Question 29

Topic: Core Terraform Workflow

A teammate opens a pull request with this Terraform configuration and says it already works. The team wants the file to follow consistent Terraform style before review, without planning or changing infrastructure.

module "network" {
source      = "./modules/network"
  cidr_block=var.cidr_block
environment = var.environment
}

Which Terraform command best fits that goal?

Options:

  • A. Run terraform plan

  • B. Run terraform fmt

  • C. Run terraform validate

  • D. Run terraform apply

Best answer: B

Explanation: terraform fmt is the Terraform command for consistent formatting. It improves readability and makes code reviews cleaner, but it is not a planning or provisioning step.

The core concept here is Terraform formatting versus Terraform workflow actions. The snippet shows inconsistent indentation and spacing, so the immediate need is style normalization, not syntax checking or infrastructure evaluation. terraform fmt updates .tf files to Terraform’s standard layout, which helps teams keep configuration readable and easier to review.

It is useful when you want to:

  • normalize spacing and indentation
  • keep code style consistent across contributors
  • reduce noisy formatting-only diffs in pull requests

By contrast, terraform validate checks whether configuration is syntactically valid and internally consistent, while terraform plan and terraform apply are about infrastructure changes. The key takeaway is that formatting helps collaboration, but it is separate from planning or provisioning.

  • Validation vs style: terraform validate checks configuration correctness, but it does not standardize layout for cleaner reviews.
  • Planning step: terraform plan previews proposed infrastructure changes, which is beyond a formatting-only goal.
  • Provisioning step: terraform apply attempts to make real changes, so it is not appropriate when the task is only code style cleanup.

Question 30

Topic: Core Terraform Workflow

A team stores Terraform code in Git and uses pull requests for review. An engineer updated a root module and several local child modules, and the code should be normalized to a consistent style across all directories before review. The team will check configuration correctness separately. What is the best next action?

Options:

  • A. Enable HCP Terraform speculative plans

  • B. Run terraform plan

  • C. Run terraform fmt -recursive

  • D. Run terraform validate

Best answer: C

Explanation: The goal is code style normalization, not correctness checking. terraform fmt -recursive standardizes Terraform file formatting across the root module and child module directories, which supports consistent pull request review.

Terraform separates formatting from validation. terraform fmt is used to rewrite configuration files into Terraform’s canonical style, such as spacing and indentation. Adding -recursive applies that formatting through the directory tree, which is useful when a change touched multiple local modules.

terraform validate checks whether a configuration is syntactically valid and internally consistent, but it does not normalize style. terraform plan compares configuration with state and proposed infrastructure changes, which is a later workflow step. HCP Terraform speculative plans help with collaborative review of proposed changes, but they do not reformat source files. The key distinction is that formatting makes code consistent, while validation checks correctness.

  • Validation vs. style: terraform validate checks correctness, not code formatting.
  • Wrong workflow stage: terraform plan is for reviewing proposed infrastructure changes, not normalizing HCL style.
  • Remote review feature: speculative plans support collaboration, but they do not rewrite files into standard format.

Question 31

Topic: Terraform Fundamentals

A team is keeping both buckets in one root module. The logs bucket must stay in us-east-1, and the archive bucket must be created in us-west-2.

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "logs" {
  bucket = "acme-logs-east"
}

resource "aws_s3_bucket" "archive" {
  bucket   = "acme-archive-west"
  provider = aws.west
}

Which change is required for this configuration to work as intended?

Options:

  • A. Move the west bucket into a separate workspace only

  • B. Add an aliased aws provider for us-west-2

  • C. Set region = "us-west-2" in aws_s3_bucket.archive

  • D. Add a second backend block for west-region state

Best answer: B

Explanation: The configuration already references aws.west, which means Terraform expects a second AWS provider configuration. When one root module must manage resources in different regions, accounts, or endpoints, you typically use multiple provider configurations and give the non-default ones aliases.

Terraform uses provider configurations to decide how and where to make API calls. In this snippet, the default aws provider points to us-east-1, so the logs bucket can use it automatically. The archive bucket is intended for another region and explicitly references aws.west, so Terraform needs a second AWS provider configuration with that alias.

provider "aws" {
  alias  = "west"
  region = "us-west-2"
}

Backends and workspaces affect state storage and state separation, not the provider endpoint, account, or region used for resource operations. The key takeaway is that managing resources in multiple regions, accounts, or endpoints from the same configuration usually requires multiple provider configurations, often with aliases.

  • Resource override fails because provider settings such as region come from provider configurations, not from a generic per-resource region switch.
  • Backend confusion fails because a backend controls where Terraform stores state, not which region or account the provider targets.
  • Workspace confusion fails because a workspace separates state instances; by itself, it does not create the missing aliased provider configuration.

Question 32

Topic: HCP Terraform

A platform team is designing its HCP Terraform organization.

Project: retail-app
  Workspaces: retail-dev, retail-stage, retail-prod
Project: shared-platform
  Workspaces: network-prod, dns-prod

Goal: group by application/team ownership
Constraint: keep each workspace state separate

Based on this note, which interpretation is best?

Options:

  • A. Group related workspaces into projects, but keep separate state per workspace.

  • B. Put every workspace in one project because projects should not reflect ownership boundaries.

  • C. Use one workspace per project so all environments share one state file.

  • D. Use variable sets instead of projects to separate applications and teams.

Best answer: A

Explanation: In HCP Terraform, projects are an organizational layer above workspaces. They help group related workspaces by application, environment set, or ownership boundary without merging separate state into one workspace.

A project in HCP Terraform is used to organize related workspaces, not to replace them. In the exhibit, retail-dev, retail-stage, and retail-prod belong together because they support the same application, while network-prod and dns-prod belong to a different ownership boundary. Keeping them as separate workspaces preserves separate Terraform state for each independently managed environment or stack.

Typical use is to:

  • group workspaces by application, team, or ownership boundary
  • keep each workspace’s state separate
  • avoid combining unrelated infrastructure just to create hierarchy

The key takeaway is that projects provide structure across workspaces, while workspaces remain the unit that holds state and runs Terraform.

  • Single shared state fails because one workspace would merge multiple environments into the same state file.
  • One giant project ignores the stated goal of grouping by application or team ownership.
  • Variable sets instead confuses shared inputs with workspace organization; variable sets do not replace projects.

Question 33

Topic: Infrastructure as Code (IaC) with Terraform

A platform team manages Terraform for dev and prod. Today, each engineer edits local .tf files and runs terraform apply from a laptop. The team wants peer review before infrastructure changes, a clear history of who changed what, and a shared workflow for collaboration. What is the best next action?

Options:

  • A. Require terraform validate and terraform plan before local apply

  • B. Use a remote backend with locking for laptop-based applies

  • C. Publish a shared module and let each engineer apply locally

  • D. Use Git pull requests and a VCS-driven HCP Terraform workspace

Best answer: D

Explanation: The best governance improvement is to store Terraform configuration in version control and review changes through pull requests. Pairing that with a VCS-driven HCP Terraform workspace gives the team a consistent, collaborative workflow and a durable change history.

When infrastructure is expressed as code, governance improves most when the code lives in version control and changes are reviewed before they are applied. A Git-based workflow provides an authoritative history of who changed the configuration, what changed, and when it changed. Pull requests add peer review, which reduces risky or accidental updates. Using a VCS-driven HCP Terraform workspace then ties plans and applies to the reviewed code in that repository, creating a more consistent team process than ad hoc laptop runs.

Remote state and locking are important for state safety, but they do not review code changes. Modules improve reuse, and validate or plan improve quality checks, but neither replaces version control, peer review, and change history for governance.

  • Remote state only helps protect the state file, but it does not create peer review or a versioned history of configuration changes.
  • Shared module only improves reuse, but engineers could still make and apply unreviewed changes from their own machines.
  • Local checks only help catch syntax or preview changes, but they do not provide an approval workflow or audit trail.

Question 34

Topic: Terraform Configuration

Terraform usually infers resource order from expression references. If one resource must be created only after another, but there is no attribute reference between them, which Terraform mechanism should you add to the configuration?

Options:

  • A. Add a lifecycle block to the dependent resource.

  • B. Run terraform apply -target for the first resource.

  • C. Add a depends_on meta-argument to the dependent resource.

  • D. Add an output block for the first resource.

Best answer: C

Explanation: Terraform automatically builds most dependencies from references in configuration. When no reference exists but ordering still matters, depends_on is the explicit way to tell Terraform about that relationship.

Terraform normally creates an execution graph by following references such as one resource using another resource’s attribute. That is called an implicit dependency. If no such reference exists, Terraform cannot safely assume an ordering relationship on its own.

In that case, use the depends_on meta-argument on the resource or module that must wait. This adds an explicit dependency to the graph so Terraform plans and applies in the required order.

A lifecycle block changes behavior such as replacement handling, not dependency inference. An output block exposes values after apply, and -target is a special-purpose CLI option, not the normal way to model dependencies in configuration.

  • lifecycle confusion fails because lifecycle settings control resource behavior, not explicit ordering between unrelated blocks.
  • output confusion fails because outputs publish values; they do not create ordering unless another block actually references them.
  • -target misuse fails because targeted apply is a manual exception and not the correct way to define ongoing dependencies.

Question 35

Topic: Terraform Configuration

Consider this Terraform configuration:

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "app" {
  vpc_id     = ?
  cidr_block = "10.0.1.0/24"
}

Which expression should replace ? to correctly connect the subnet to the VPC?

Options:

  • A. aws_vpc.main

  • B. "aws_vpc.main.id"

  • C. resource.aws_vpc.main.id

  • D. aws_vpc.main.id

Best answer: D

Explanation: Terraform connects managed resources by referencing a specific attribute from one resource in another resource’s argument. Using aws_vpc.main.id passes the VPC ID value and creates an implicit dependency between the subnet and the VPC.

Terraform uses resource attribute references in the form resource_type.resource_name.attribute to connect Terraform-managed objects. Here, the subnet needs a single VPC ID value, so aws_vpc.main.id is the correct expression. Because the subnet reads an attribute from the VPC resource, Terraform also knows the subnet depends on that VPC and can order planning and creation correctly.

  • Use a specific attribute such as id, arn, or name.
  • Do not quote the expression if you want Terraform to evaluate it.
  • Do not pass the whole resource object when the argument expects one scalar value.

The key takeaway is that attribute references let Terraform share real resource values without hard-coding them.

  • Extra prefix resource.aws_vpc.main.id is not valid Terraform reference syntax.
  • Quoted text "aws_vpc.main.id" is a literal string, so Terraform would not evaluate it as a reference.
  • Wrong value type aws_vpc.main refers to the full resource object, not the single id value needed by vpc_id.

Question 36

Topic: Terraform Modules

A teammate says the version line in the module "network" block is pinning the AWS provider. Review the configuration.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.31"
    }
  }
}

module "network" {
  source  = "examplecorp/network/aws"
  version = "1.4.2"
}

Which dependency is actually being constrained by version = "1.4.2"?

Options:

  • A. The hashicorp/aws provider plugin version

  • B. The Terraform CLI version for this root module

  • C. The examplecorp/network/aws module release

  • D. The backend or state format version

Best answer: C

Explanation: The version argument shown inside the module block constrains the module release because the source uses a registry-style module address. Provider versioning is separate and is already handled by the aws entry in required_providers.

Terraform treats modules and providers as different dependency types. In this snippet, source = "examplecorp/network/aws" is a registry-style module source, so version = "1.4.2" selects that module’s release. The AWS provider is constrained elsewhere: under terraform.required_providers, where hashicorp/aws is pinned with ~> 5.31.

If you wanted to constrain the Terraform CLI itself, you would use required_version in the terraform block. Backend and state versions are not controlled by the version argument in a module block.

The key distinction is that module versioning and provider versioning are separate, even when both appear in the same configuration.

  • Provider confusion The option about the AWS provider is incorrect because provider constraints live in required_providers, not in a module block.
  • CLI version mix-up The option about the Terraform CLI would require a required_version setting in the terraform block.
  • State/backend mix-up The option about backend or state format is unrelated because this snippet shows no backend settings and module version does not version state.

Question 37

Topic: Terraform Configuration

A team runs this configuration and sees intermittent apply failures because module.app starts before firewall rules created by module.network are ready. Provider credentials are valid, and module.app does not need any values from module.network.

module "network" {
  source = "./modules/network"
}

module "app" {
  source       = "./modules/app"
  service_name = "billing"
}

What is the best configuration fix?

Options:

  • A. Add depends_on = [module.network] to module "app"

  • B. Run terraform init again to rebuild dependencies

  • C. Use terraform apply -target=module.network before each full apply

  • D. Add another provider configuration inside module "app"

Best answer: A

Explanation: Terraform determines apply order from references and explicit dependencies. Because module.app has no reference to module.network, Terraform has no relationship information to enforce order, so an explicit depends_on is the right fix.

Terraform builds a dependency graph from expressions that reference other objects, such as using one module’s output in another module’s input. In this example, the two modules are separate in configuration, so Terraform can treat them as independent and run them without a guaranteed order.

When a real dependency exists but no data value is exchanged, use depends_on to declare that hidden relationship explicitly. That matches the stem: the problem is missing dependency information, not a provider or authentication issue.

Using depends_on is the durable fix because it updates the configuration itself instead of relying on a one-off command.

  • Re-running init only initializes providers, modules, and backends; it does not invent missing graph relationships.
  • Adding a provider block targets provider selection or credentials, but the stem already says authentication is valid.
  • Using -target can force a one-time sequence, but it is a workaround rather than the normal way to model dependencies.

Question 38

Topic: Terraform Fundamentals

A Terraform root module must manage AWS resources in two regions and Azure resources in the same configuration. Which approach is correct?

Options:

  • A. Use required_providers entries only; Terraform creates the needed instances automatically.

  • B. Use workspaces to combine multiple provider contexts in one configuration.

  • C. Use separate backends so each platform gets its own provider selection.

  • D. Use separate provider blocks, add alias for extra instances, and reference them explicitly.

Best answer: D

Explanation: Terraform uses provider blocks to configure actual provider instances. When the same provider is needed more than once, such as AWS in multiple regions, you add an alias and point resources or modules to the right instance. This is different from required_providers, backends, or workspaces.

Terraform separates provider requirements from provider configuration. The required_providers block tells Terraform which provider plugins and versions are needed, but provider blocks create the usable provider instances. If you need multiple platforms, declare each provider. If you need multiple instances of the same provider, declare another provider block with an alias, then select it from resources with the provider meta-argument or pass it into a module.

provider "aws" { region = "us-east-1" }
provider "aws" { alias = "west" region = "us-west-2" }
provider "azurerm" { features {} }

A backend manages state storage, and workspaces separate state, but neither one chooses provider instances.

  • Requirements only listing providers in required_providers installs plugins and sets version constraints, but it does not configure usable provider instances.
  • Backend confusion a backend controls where state is stored and locked, not which provider configuration a resource uses.
  • Workspace confusion workspaces separate state for the same configuration, but they do not merge or create multi-provider setups.

Question 39

Topic: HCP Terraform

A team already stores its Terraform configuration in a shared Git repository, but engineers still run plan and apply from their laptops. They want HCP Terraform to centralize state, run operations remotely, and automatically start runs when repository changes are pushed. Which approach best fits this requirement?

Options:

  • A. Use terraform import to move the workflow into HCP Terraform.

  • B. Keep local execution and add terraform validate before each apply.

  • C. Use CLI-driven remote operations from each engineer’s laptop.

  • D. Connect the repository to an HCP Terraform workspace and use a VCS-driven workflow.

Best answer: D

Explanation: This scenario calls for automatic remote runs from version control changes, which is exactly what a VCS-driven HCP Terraform workspace provides. It also centralizes state and team collaboration in the managed platform.

The key requirement is that repository changes should automatically trigger remote Terraform runs in HCP Terraform. That is the purpose of a VCS-driven workflow: the workspace is connected to a source repository, and commits or pull request events can queue plans and applies while state stays centralized.

CLI-driven remote operations also use HCP Terraform for execution and state, but the run is still started from the Terraform CLI rather than directly from VCS events. terraform import is for bringing existing infrastructure resources into Terraform state, not for changing how teams collaborate or trigger runs. Commands like terraform validate help check configuration correctness, but they do not migrate a local workflow into managed HCP Terraform operations.

The deciding clue is the need for repository-triggered remote collaboration.

  • CLI-driven mismatch still depends on a user running Terraform commands, so it does not automatically start runs from repository changes.
  • Import confusion brings existing resources under Terraform state management; it does not convert a team to an HCP Terraform collaboration model.
  • Validation only improves configuration quality but leaves execution and workflow ownership on local machines.

Question 40

Topic: Maintain Infrastructure with Terraform

A team uses the same Terraform configuration in dev, test, and prod. During a local terraform plan, an engineer gets an unclear error and needs more diagnostic detail for troubleshooting. They must keep the shared configuration unchanged and avoid making infrastructure changes while they investigate. What is the best next action?

Options:

  • A. Add a variable "TF_LOG" block and rerun terraform plan

  • B. Run the configuration in HCP Terraform instead of locally

  • C. Set TF_LOG to DEBUG and rerun terraform plan

  • D. Rerun with terraform apply for more error detail

Best answer: C

Explanation: TF_LOG is an environment-driven Terraform CLI control for increasing diagnostic output during troubleshooting. Setting it to a verbose level and rerunning terraform plan gives more detail without editing reusable HCL or risking infrastructure changes.

When Terraform needs to show more internal detail during troubleshooting, the correct tool is the TF_LOG environment variable. Because it is environment-driven, it changes Terraform’s runtime verbosity for the current process or session instead of changing the shared .tf configuration used across environments. Using it with terraform plan also satisfies the safe-review requirement, because plan inspects proposed actions without applying them.

Common log levels include INFO, DEBUG, and TRACE, with higher levels producing more detail. After troubleshooting, you can unset the variable or reduce the level again. The key idea is that TF_LOG controls Terraform CLI diagnostics, while configuration files should describe infrastructure, not temporary debugging behavior.

The closest trap is changing the execution workflow instead of simply enabling temporary CLI logging.

  • Input variable confusion fails because defining TF_LOG in HCL creates a normal Terraform variable, not a CLI logging control.
  • Unsafe step fails because terraform apply can change real infrastructure, which breaks the safe-review requirement.
  • Workflow overreach fails because switching to HCP Terraform is a larger workflow change and does not directly solve temporary local diagnostic logging.

Question 41

Topic: Maintain Infrastructure with Terraform

A cloud engineer needs more detailed Terraform CLI diagnostics while troubleshooting a failed run, without changing any .tf files. Which action is the correct way to increase Terraform’s log verbosity?

Options:

  • A. Set a TF_VAR_* environment variable

  • B. Run terraform validate

  • C. Configure a different backend

  • D. Set the TF_LOG environment variable

Best answer: D

Explanation: Terraform uses the TF_LOG environment variable to increase diagnostic output from the CLI. This is a troubleshooting feature controlled by the shell environment, so it does not require editing Terraform configuration files.

TF_LOG is the standard Terraform environment variable for turning on verbose logging. When you set it to a log level such as TRACE, DEBUG, INFO, WARN, or ERROR, Terraform prints more internal diagnostic details to help investigate problems during commands like plan or apply.

This is useful because it is temporary and environment-driven:

  • it affects the current shell or process
  • it does not change your HCL configuration
  • it is intended for troubleshooting CLI behavior

By contrast, normal workflow commands or input variables do not enable detailed internal logs. The key takeaway is that Terraform logging verbosity is controlled through TF_LOG, not through configuration blocks or routine formatting/validation commands.

  • Input variables using TF_VAR_* pass values into Terraform variables, but they do not change CLI logging behavior.
  • Validation command checks whether configuration is syntactically valid, but it does not enable verbose diagnostic logs.
  • Backend choice controls where state is stored and how it is accessed, not how much troubleshooting output Terraform prints.

Question 42

Topic: Terraform Configuration

Which statement correctly describes a standard way Terraform receives an input variable value?

Options:

  • A. An environment variable named TF_VAR_region can set variable "region" {}.

  • B. Values in outputs.tf are automatically reused as input variables.

  • C. Terraform stores input variable values in .terraform.lock.hcl.

  • D. Any environment variable starting with TF_ can set an input variable.

Best answer: A

Explanation: Terraform supports several common input variable sources, including defaults, variable definition files, command-line flags, and environment variables. For environment variables, the recognized format is TF_VAR_<variable_name>, so TF_VAR_region is valid for a variable named region.

Input variables in Terraform can be supplied in several standard ways: a default in the variable block, a variable definition file such as terraform.tfvars or .auto.tfvars, a command-line flag like -var, or an environment variable. When using environment variables, Terraform requires a strict naming pattern: TF_VAR_ followed by the exact input variable name.

That is why TF_VAR_region correctly sets variable "region" {}. Other TF_ names are not automatically treated as input variables, and files like .terraform.lock.hcl or outputs.tf serve different purposes.

The key distinction is between actual variable input mechanisms and other Terraform configuration or metadata files.

  • Too broad: a generic TF_ prefix is not enough; Terraform only maps TF_VAR_<name> to input variables.
  • Wrong file purpose: .terraform.lock.hcl tracks provider dependency selections, not variable values.
  • Wrong concept: outputs.tf defines output values from a configuration, not input values for future runs.

Question 43

Topic: Infrastructure as Code (IaC) with Terraform

A team stores Terraform for production in Git, and the repository requires pull request approval before merging to main. Their HCP Terraform workspace is configured as shown:

Workspace: prod-network
VCS repository: acme/networking
Tracked branch: main
Pull requests: speculative plans before merge
Run history: retained in workspace

Which governance benefit is best supported by this setup?

Options:

  • A. State files are no longer needed for this workspace.

  • B. Changes are reviewed before apply and remain traceable later.

  • C. Failed infrastructure changes are automatically rolled back.

  • D. Drift is automatically prevented and corrected in all environments.

Best answer: B

Explanation: This setup improves governance by putting Terraform changes in version control, requiring peer review through pull requests, and preserving workspace run history. That creates approval checkpoints before production changes and a clear record of what changed, when, and from which code revision.

Terraform governance improves when infrastructure changes follow the same controls as application code. Here, the configuration is stored in Git, pull requests are reviewed before merge, HCP Terraform generates speculative plans for those pull requests, and the workspace keeps run history. Together, those features make changes both reviewable and traceable: reviewers can inspect the code diff and the proposed plan before merge, and teams can later audit which commit led to a given run or apply.

  • Version control records who changed the configuration and when.
  • Peer review adds a human approval checkpoint before production updates.
  • Run history preserves a searchable record of past plans and applies.

This strengthens governance and accountability, but it does not by itself guarantee zero drift or automatic rollback.

  • Drift control is too strong because review and history improve oversight, but they do not automatically prevent or repair every out-of-band change.
  • No state needed is incorrect because Terraform still relies on state, even when HCP Terraform manages it remotely.
  • Automatic rollback is incorrect because Terraform does not automatically revert infrastructure after a failed or completed apply.

Question 44

Topic: Core Terraform Workflow

Which sequence correctly describes the core Terraform workflow for a new working directory?

Options:

  • A. Write configuration, run terraform plan, review changes, run terraform init, then run terraform apply

  • B. Write configuration, run terraform init, run terraform apply, then review the resulting changes

  • C. Write configuration, run terraform validate, inspect state, then run terraform apply

  • D. Write configuration, run terraform init, run terraform plan, review changes, then run terraform apply

Best answer: D

Explanation: The core Terraform workflow is to write configuration, initialize the directory, generate a plan, review that plan, and then apply it. This order ensures Terraform is ready to work with providers and backends before proposing and making infrastructure changes.

Terraform’s core workflow is designed to make infrastructure changes predictable. After writing configuration, terraform init prepares the working directory by setting up required providers, modules, and backend settings. Then terraform plan compares the configuration with the current state and real infrastructure to show the proposed actions. You review that plan to confirm the intended creates, updates, or destroys before making any changes. Finally, terraform apply performs the approved actions.

Helpful commands like terraform fmt and terraform validate can improve configuration quality, but they do not replace initialization, planning, review, and apply in the main workflow.

  • Reviewing after terraform apply is too late, because changes have already been made.
  • Running terraform plan before terraform init is incorrect because the directory is not initialized yet.
  • terraform validate and state inspection are useful checks, but they do not replace generating and reviewing a plan.

Question 45

Topic: Maintain Infrastructure with Terraform

A team refactored resources into modules and wants to confirm the exact resource addresses Terraform is currently tracking in state, without changing infrastructure. Which CLI command should they run?

Options:

  • A. terraform state list

  • B. terraform validate

  • C. terraform import

  • D. terraform state show

Best answer: A

Explanation: terraform state list is the inspection command for seeing which resource addresses are currently recorded in state. It helps confirm current state mappings after refactoring, without changing infrastructure.

Terraform’s state subcommands are used to inspect and work with the resources Terraform already tracks in state. When the goal is to see the current resource mappings by address, terraform state list is the appropriate command because it outputs the addresses stored in state, including module paths when applicable.

If you instead need details for one tracked object, use terraform state show with a specific address. Commands like import and validate serve different purposes: one brings existing infrastructure under state management, and the other checks configuration syntax and internal consistency. The key distinction is that state list answers “what addresses are in state right now?”

  • Specific object details fits terraform state show, but that command expects a single resource address and returns its stored attributes.
  • Bring existing resources under management describes terraform import, which changes state rather than inspecting current mappings.
  • Check configuration correctness describes terraform validate, which evaluates configuration files, not stored state entries.

Question 46

Topic: Terraform Modules

Review this configuration:

# root module
variable "project_name" {
  default = "demo"
}

module "app" {
  source = "./modules/app"
}

The child module ./modules/app declares variable "project_name" {} and uses var.project_name. Which statement is correct?

Options:

  • A. terraform init copies root variables into child modules.

  • B. Terraform state exposes root variables to every child module.

  • C. The child module automatically receives demo from the root variable.

  • D. The root module must pass project_name = var.project_name in the module block.

Best answer: D

Explanation: Terraform modules have separate variable scopes. A child module does not automatically inherit arbitrary root-module values, even if the variable names match, so the root must pass the value through the module block.

In Terraform, each module has its own input variable scope. A variable declared in the root module is available to the root module, but a child module can use that value only if the root passes it explicitly as a module input. Matching variable names alone do not share values across modules, and Terraform commands or state do not change that boundary.

module "app" {
  source       = "./modules/app"
  project_name = var.project_name
}

That explicit input assignment is what makes the root value available inside the child module.

  • Automatic inheritance is wrong because child modules do not see root-module variables unless values are passed in.
  • init misconception fails because terraform init installs providers and modules and prepares the working directory; it does not pass variable values.
  • State confusion is wrong because state is not a global variable-sharing mechanism between modules.

Question 47

Topic: Core Terraform Workflow

An engineer generated the following plan and wants to skip review and run terraform apply -auto-approve during a short maintenance window.

# aws_instance.web must be replaced
-/+ resource "aws_instance" "web" {
      ~ ami = "ami-0abc" -> "ami-0def" # forces replacement
        id  = "i-0123456789"
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Based on this output, what is the best next step?

Options:

  • A. Run terraform validate because syntax checks confirm a safe apply

  • B. Re-run terraform init because replacement needs reinitialization

  • C. Review why the instance will be replaced before applying

  • D. Apply now because the plan shows zero net resource growth

Best answer: C

Explanation: This plan shows a replacement, not a harmless update. In Terraform output, -/+ means destroy and create, so applying without reviewing the plan can cause unwanted changes even if the total resource count stays the same.

A successful plan does not mean the changes are safe or desired. In this plan, the ami change is marked # forces replacement, and the -/+ prefix confirms that Terraform will replace aws_instance.web rather than update it in place. If the engineer runs terraform apply -auto-approve without understanding that plan, Terraform will destroy the existing instance and create a new one.

Before applying, the right action is to review why replacement is planned and confirm that the disruption is intentional. This is exactly why reading the plan matters before approval or apply, especially when using -auto-approve. A net-zero resource count can still hide a destructive change.

  • Net-zero trap The add and destroy counts do not cancel out operationally; the existing instance would still be replaced.
  • Wrong workflow step terraform init prepares the working directory, providers, modules, and backend; it is not required just because a resource is being replaced.
  • Validation limit terraform validate checks configuration correctness, not whether the planned infrastructure changes are acceptable.

Question 48

Topic: Terraform Configuration

A platform team maintains a reusable Terraform module used by dev, staging, and prod through separate HCP Terraform workspaces. They want callers to provide the same input structure in every environment and want mistakes caught early during plan review. The module currently declares this input:

variable "app_config" {
  type = any
}

Callers have recently passed values with missing keys and wrong value types. What is the best next change?

Options:

  • A. Change app_config to an object(...) type with explicit attribute types

  • B. Move the expected values into locals so each workspace inherits the same structure

  • C. Add an output that documents the expected fields for app_config

  • D. Use an HCP Terraform variable set to share the current any input across workspaces

Best answer: A

Explanation: The best fix is to replace type = any with a specific complex type such as object(...). That makes the module’s variable contract explicit, improves reuse across environments, and helps Terraform catch incorrect input shapes and value types during planning rather than later in the workflow.

Type constraints define what shape and value types a module input must have. When a reusable module uses any, Terraform accepts almost anything, so callers can accidentally pass missing attributes, extra unexpected structures, or wrong primitive types. Using a complex type like object({ name = string, replicas = number, tags = map(string) }) makes the contract clear to every caller and allows Terraform to validate the structure before apply.

This is especially useful when the same module is used across multiple environments or HCP Terraform workspaces:

  • it improves consistency between callers
  • it reduces accidental misuse of inputs
  • it gives earlier feedback during plan and review

Documentation and shared variables can help teams collaborate, but they do not replace a strong variable type contract enforced by Terraform itself.

  • Using locals can centralize values inside a configuration, but it does not enforce what external callers are allowed to pass into the module.
  • Adding outputs may describe the expected structure, but outputs are for exposing data after evaluation, not validating module inputs.
  • Using variable sets can share values across HCP Terraform workspaces, but they do not solve the weak contract caused by type = any.

Question 49

Topic: Core Terraform Workflow

A cloud engineer just cloned a repository. No Terraform commands have been run in this directory yet.

terraform {
  required_providers {
    random = {
      source  = "hashicorp/random"
      version = "~> 3.6"
    }
  }

  backend "local" {
    path = "state/terraform.tfstate"
  }
}

module "labels" {
  source = "git::https://example.com/modules/labels.git"
}

What is terraform init responsible for here?

Options:

  • A. Configuring the backend and installing required providers and modules

  • B. Making the described infrastructure changes and updating state

  • C. Checking the configuration for syntax and internal consistency

  • D. Creating an execution plan of proposed infrastructure changes

Best answer: A

Explanation: terraform init is the setup step for a Terraform working directory. In this example, it initializes the configured backend, installs the random provider, and downloads the Git-based child module before later commands like validate, plan, or apply are used.

The core purpose of terraform init is to prepare a working directory so Terraform can operate in it. From the shown configuration, that means reading the backend block, setting up the local backend configuration, installing the required provider version for hashicorp/random, and downloading the child module from the Git source.

It does not compare configuration to real infrastructure, and it does not create or change resources. Those responsibilities belong to later workflow steps:

  • terraform validate checks configuration validity.
  • terraform plan shows proposed changes.
  • terraform apply performs those changes.

A good way to remember it is that init sets up the directory, while the other commands inspect or act on infrastructure.

  • The syntax-check option describes terraform validate, which focuses on configuration correctness rather than directory setup.
  • The execution-plan option describes terraform plan, which needs an initialized directory first.
  • The infrastructure-change option describes terraform apply, which can modify real resources and state.

Question 50

Topic: Infrastructure as Code (IaC) with Terraform

A platform team supports dev, stage, and prod with nearly identical Terraform code copied into separate directories. They want faster delivery, consistent infrastructure across environments, and an auditable review step before changes are applied by multiple engineers.

What is the best IaC pattern to adopt?

Options:

  • A. Replace repeated resources with data sources so each environment reads existing infrastructure

  • B. Share one local state file across all environments to keep resources synchronized

  • C. Create a reusable module, pin its version, and use VCS-driven HCP Terraform workspaces per environment

  • D. Keep separate root configurations and rely on terraform fmt before each local apply

Best answer: C

Explanation: The best pattern is to move the repeated configuration into a reusable module and consume that module from separate environment workspaces. Pairing that with VCS-driven HCP Terraform runs adds an auditable review process, shared remote state handling, and more predictable changes across teams.

This scenario is asking for an IaC pattern that improves reuse, consistency, collaboration, and auditability at the same time. A reusable Terraform module lets the team define the common infrastructure once and use it across dev, stage, and prod, which reduces copy-paste drift. Pinning the module version makes rollouts more predictable because each environment can intentionally adopt a known version.

Using VCS-driven HCP Terraform workspaces adds the review and collaboration workflow:

  • Changes are proposed through version control.
  • Plans are generated remotely and can be reviewed before apply.
  • Each environment keeps separate state in its own workspace.
  • Runs are easier to audit than ad hoc local execution.

The closest distractors either improve formatting only, misuse data sources, or reduce state safety instead of improving it.

  • Formatting only: terraform fmt improves style, but it does not create reusable configuration, shared review, or safer collaboration.
  • Wrong construct: data sources read existing information; they do not replace reusable resource definitions for managed infrastructure.
  • Unsafe state pattern: sharing one local state file across environments increases risk and breaks environment isolation rather than improving predictability.

Questions 51-57

Question 51

Topic: Terraform Configuration

A team wants Terraform to add a subnet to an already existing VPC without managing the VPC itself. Consider this configuration:

data "aws_vpc" "shared" {
  id = "vpc-0abc1234"
}

resource "aws_subnet" "app" {
  vpc_id     = data.aws_vpc.shared.id
  cidr_block = "10.0.10.0/24"
}

Which interpretation is correct?

Options:

  • A. Create the VPC and subnet during apply

  • B. Read both objects without managing either one

  • C. Import the VPC into state automatically

  • D. Read the existing VPC and manage the new subnet

Best answer: D

Explanation: In Terraform, a data block reads information about an existing object, while a resource block manages an object’s lifecycle. Here, the VPC is only looked up for its ID, and the subnet is the object Terraform will create and track.

resource and data blocks have different roles in Terraform. A resource block declares infrastructure that Terraform should manage, so Terraform can plan to create, update, or destroy that object and record it in state. A data block only looks up information about something that already exists and makes its attributes available to the configuration.

In this snippet, data "aws_vpc" "shared" reads the existing VPC identified by the given ID. Terraform does not take ownership of that VPC just because it is referenced. The resource "aws_subnet" "app" block is different: it declares a new subnet that Terraform should manage, using the VPC ID returned by the data source.

The key distinction is that reading an object is not the same as managing its lifecycle.

  • The option claiming Terraform creates both objects confuses a data lookup with a managed resource.
  • The option claiming the VPC is imported automatically fails because import is a separate action and no VPC resource block is shown.
  • The option claiming both objects are only read ignores that the subnet is declared with a resource block.

Question 52

Topic: Core Terraform Workflow

Which Terraform command checks whether a configuration is syntactically valid and internally consistent, rather than only rewriting files into Terraform’s canonical style?

Options:

  • A. terraform init

  • B. terraform validate

  • C. terraform plan

  • D. terraform fmt

Best answer: B

Explanation: terraform validate is the command used for correctness checking. It verifies that the configuration is syntactically valid and internally consistent, whereas terraform fmt only rewrites files to standard Terraform formatting.

Terraform separates style normalization from correctness checking. Use terraform fmt when you want consistent spacing, indentation, and layout in .tf files. Use terraform validate when you want Terraform to check that the configuration is syntactically valid and that its internal references and structure make sense.

terraform validate does not create an execution plan or change infrastructure. It is commonly used after writing or editing configuration to catch errors early. By contrast, terraform fmt improves readability and consistency but does not prove the configuration is correct.

A useful shortcut is: fmt is for how code looks, validate is for whether the configuration is valid.

  • Formatting only The option using terraform fmt is tempting because it works on configuration files, but it does not check correctness.
  • Planning is later The option using terraform plan evaluates proposed infrastructure changes, not just basic configuration validity.
  • Initialization is setup The option using terraform init prepares the working directory, such as providers and modules, but it is not the validation step.

Question 53

Topic: Terraform Configuration

A team uses the same Terraform module in dev and prod HCP Terraform workspaces. They need each resource name to be <app>-<workspace> in lowercase, tags to combine shared and environment-specific values, and all changes to go through the normal HCP Terraform plan review before apply. A developer says this requires new provider behavior because the cloud API must build the final values. What is the best next action?

Options:

  • A. Enter the final names and full tag maps separately in each workspace as manual variables.

  • B. Add locals that use format(), lower(), and merge(), reference them in resource arguments, and review the HCP Terraform plan.

  • C. Open a provider feature request so the API can compose names and tags during create and update calls.

  • D. Create a Sentinel policy set that generates the names and tags during each run.

Best answer: B

Explanation: This is a Terraform language problem, not a provider capability problem. Use HCL expressions and functions in reusable configuration to derive the final values, then let HCP Terraform show the exact result in the plan before apply.

Terraform language features such as expressions, locals, and functions are used to construct values inside configuration. Terraform evaluates those values during planning and then passes the final strings, lists, or maps to the provider. In this scenario, lowercase names and merged tags are value-construction requirements, so the right solution is to define derived values in HCL and reuse them across environments.

  • Build the name with functions such as format() and lower().
  • Combine shared and environment-specific tags with merge().
  • Reference those derived values in resources and review the HCP Terraform plan.

The key takeaway is that providers handle API interactions, while HCL expressions and functions handle value construction.

  • Provider confusion waiting for a provider enhancement is unnecessary because Terraform can already compute the final argument values before provider calls.
  • Manual per-workspace input supplying finished names and tags in each workspace weakens reuse and increases the chance of inconsistent environments.
  • Wrong tool Sentinel is for policy checks and governance, not for generating resource argument values in configuration.

Question 54

Topic: Core Terraform Workflow

A team already initialized a Terraform working directory. They then change a child module block so its source points to a different registry module. Which command should they run before terraform plan?

Options:

  • A. terraform validate

  • B. terraform init

  • C. terraform fmt

  • D. terraform apply

Best answer: B

Explanation: terraform init prepares the working directory by installing providers, downloading modules, and configuring backend data. When a module source changes, Terraform must reinitialize so the new module code is available before planning.

The core concept is that terraform init is required not only the first time you use a working directory, but also when provider, backend, or module dependencies change materially. A changed child module source means Terraform may need to download different module code, so re-running init updates the working directory before terraform plan evaluates the configuration.

terraform validate checks whether the configuration is syntactically valid and internally consistent, but it does not install or update dependencies. terraform fmt only rewrites configuration files into standard formatting. terraform apply creates or updates infrastructure, but it should come after proper initialization and planning.

A good rule: if the configuration changes what Terraform must download or configure behind the scenes, run terraform init again.

  • Validation only checks configuration correctness; it does not fetch a newly referenced module.
  • Formatting only changes file layout and style, not Terraform dependencies.
  • Apply is not initialization because dependency setup should happen before planning and any infrastructure changes.

Question 55

Topic: Terraform Fundamentals

A cloud engineer deleted a resource outside Terraform and recreated it manually. The configuration still uses the same resource address, but the remote object now has a different ID. Instead of using supported Terraform workflows, the engineer wants to open the state file in a text editor and replace the old ID by hand. Why is this risky?

Options:

  • A. State affects outputs only, not create, update, or destroy decisions.

  • B. Terraform ignores manual state edits because plan reads only configuration.

  • C. It can map the resource address to the wrong object, causing misleading drift and bad lifecycle actions.

  • D. Manual edits are safe when the new object has the same type.

Best answer: C

Explanation: Terraform state is the record Terraform uses to map each resource address to a specific real object. If you hand-edit that mapping carelessly, Terraform can misread drift and act on the wrong object during later plans or applies.

Terraform state is not just a cache. It stores the relationship between a resource address in configuration and the real remote object Terraform believes it manages, plus metadata used during planning. If you manually swap an ID or edit entries carelessly, Terraform may believe the wrong object belongs to that address. That can hide real drift, confuse future plans, and cause broken lifecycle behavior such as unexpected replacement or destruction.

  • Configuration declares the desired objects.
  • State records which real objects are already managed.
  • plan compares configuration, state, and provider-read data.

Because state directly affects those decisions, manual text editing is risky. Safer approaches use supported workflows such as terraform import or Terraform state commands.

  • The option claiming plan reads only configuration fails because Terraform uses state to know what it already manages.
  • The option claiming matching resource type makes manual edits safe fails because the address-to-object binding can still be wrong.
  • The option claiming state affects only outputs fails because state directly influences create, replace, and destroy behavior.

Question 56

Topic: Terraform Configuration

A team reviews this Terraform configuration and wants the dynamic logic to stay readable for new engineers.

variable "create_bucket" {
  type    = bool
  default = true
}

locals {
  bucket_count = length(compact([
    var.create_bucket ? "create" : ""
  ]))
}

resource "aws_s3_bucket" "logs" {
  count  = local.bucket_count
  bucket = "example-logs"
}

Which next step best improves readability without changing the intent?

Options:

  • A. Move the resource into a child module

  • B. Keep the local because more functions are preferred

  • C. Replace count with a dynamic block

  • D. Use count = var.create_bucket ? 1 : 0 directly

Best answer: D

Explanation: The shown local turns a boolean into a temporary list, removes empty values, and then counts the result just to produce 1 or 0. A direct conditional for count is simpler and keeps the resource intent clear.

Terraform supports dynamic expressions and functions, but they should clarify the configuration rather than obscure it. In this example, the real intent is simple: create one bucket when create_bucket is true, otherwise create none. The compact(...) and length(...) chain technically works, but it hides that basic decision behind extra steps.

A clearer version is:

count = var.create_bucket ? 1 : 0

That keeps the primary infrastructure intent visible at the resource itself. Dynamic blocks are for generating nested blocks, not deciding whether a top-level resource exists, and a child module would add indirection without solving the readability problem.

  • More functions is a trap because Terraform does not prefer complex expressions when a simple conditional is clearer.
  • Dynamic block is incorrect because it generates nested configuration blocks, not whole resources.
  • Child module adds another layer to read and is best used for reuse or separation, not for hiding simple count logic.

Question 57

Topic: Terraform State Management

A platform team manages one shared environment with Terraform. Two engineers sometimes trigger runs within minutes of each other. The team wants reviewed changes, shared state, and protection against simultaneous updates to the same state. What is the best next step?

Options:

  • A. Commit terraform.tfstate to Git and review merge conflicts.

  • B. Run terraform apply -lock=false to avoid blocked runs.

  • C. Require local terraform plan before every terraform apply.

  • D. Use an HCP Terraform workspace for remote runs and state locking.

Best answer: D

Explanation: An HCP Terraform workspace is the best fit because it combines shared remote state with state locking during runs. State locking prevents concurrent operations from writing incompatible changes to the same state at the same time, which is exactly the team’s safety requirement.

State locking is Terraform’s mechanism for protecting a shared state file from concurrent modification. When one run has the lock, another run cannot update the same state until the first operation finishes or releases the lock. That prevents overlapping writes that could leave Terraform with inconsistent resource tracking.

In this scenario, an HCP Terraform workspace is the best choice because it provides remote state, locking, and a central place to review plans and applies for team collaboration. It solves both the shared-state problem and the concurrent-write problem. By contrast, review steps alone do not coordinate writers, and storing state in Git is not a safe substitute for a locking backend.

The key takeaway is that safe teamwork with shared Terraform state requires a backend or platform that enforces state locking.

  • Requiring local plan helps review changes, but it does not stop two applies from trying to write the same state.
  • Committing terraform.tfstate to Git shares the file, but Git merge handling is not Terraform state locking.
  • Using -lock=false disables the protection that prevents concurrent state updates.

Continue with full practice

Use the Terraform Associate (004) Practice Test page for the full IT Mastery practice bank, mixed-topic practice, timed mock exams, explanations, and web/mobile app access.

Try Terraform Associate (004) on Web View Terraform Associate (004) Practice Test

Focused topic pages

Free review resource

Read the Terraform Associate (004) Cheat Sheet for compact concept review before returning to timed practice.

Revised on Sunday, May 24, 2026