Skip to content

002 · Domain 2: Terraform State and Backend Operations · 13% of the exam

Task 2.1: Create and manage Remote Backend and Remote State Configuration

Choosing and configuring where state lives: backend blocks and partial configuration, the S3 backend's lock file, state migration with init, the cloud block for HCP Terraform, and reading another configuration's outputs with terraform_remote_state.

Study it

  • Remote backends, partial configuration, migration and terraform_remote_state

    Lesson coming

  • Why state needs a lock: concurrent runs against one state

    Partly covered by: Race Conditions

Sample questions

Try each one before opening the answer. Every option is explained, with the HashiCorp documentation page that proves it.

Question 1 · choose 1

A pipeline runs terraform init with -backend-config="token=..." using a short-lived token, then saves a plan. After approval, a later job runs terraform apply tfplan with a freshly issued token in its environment, and the apply fails because the backend credentials have expired. Security also flagged that the token appears in a plan artifact. What should the team change?

  1. APass a fresh -backend-config token from the job's environment to terraform apply tfplan
  2. BRun terraform init -reconfigure in the apply job before applying the saved plan
  3. CStore the token in the backend block itself to have plan and apply always read exactly the same value
  4. DLeave the credential out of backend settings and supply it as an environment variable in each job
Show the answer and why
  • APass a fresh -backend-config token from the job's environment to terraform apply tfplan

    Incorrect

    A saved plan carries the backend configuration captured at plan time, and apply uses that stored configuration rather than new settings.

  • BRun terraform init -reconfigure in the apply job before applying the saved plan

    Incorrect

    Reinitializing changes the working directory, but applying a saved plan still uses the backend configuration recorded inside the plan file.

  • CStore the token in the backend block itself to have plan and apply always read exactly the same value

    Incorrect

    Hard-coded credentials are also written into .terraform and plan files, which is the leak security flagged, and the stored token still expires.

  • DLeave the credential out of backend settings and supply it as an environment variable in each job

    Correct

    Credentials from the environment are not captured in .terraform or the plan file, and each job can use its own current value.

Terraform writes backend settings, including any given with -backend-config, in plain text to .terraform/terraform.tfstate and to every plan file, and a saved plan is applied with the settings it captured. Environment variables keep secrets out of both and let plan and apply use different credentials.

Question 2 · choose 1

A network configuration stores its state in an S3 backend with the key network/terraform.tfstate and uses CLI workspaces dev and prod. An application configuration, which uses workspaces with the same names, must read the network outputs of the matching workspace. How should the application's terraform_remote_state data source be configured?

  1. Abackend = "s3" and key = "${terraform.workspace}/network/terraform.tfstate" in the config object
  2. Bbackend = "s3" and workspace_key_prefix = terraform.workspace in config
  3. Cbackend = "s3", the same bucket, key and region in config, and workspace = terraform.workspace
  4. DA tfe_outputs data source that names the network workspace for each environment
Show the answer and why
  • Abackend = "s3" and key = "${terraform.workspace}/network/terraform.tfstate" in the config object

    Incorrect

    The S3 backend stores non-default workspaces under its own workspace path, so a hand-built key does not match where the state lives.

  • Bbackend = "s3" and workspace_key_prefix = terraform.workspace in config

    Incorrect

    workspace_key_prefix names the prefix folder, not the workspace, so this looks under a prefix such as dev/ that holds no state.

  • Cbackend = "s3", the same bucket, key and region in config, and workspace = terraform.workspace

    Correct

    The workspace argument selects a named workspace in a backend that supports workspaces, and the backend resolves the matching state path.

  • DA tfe_outputs data source that names the network workspace for each environment

    Incorrect

    tfe_outputs reads outputs from HCP Terraform or Terraform Enterprise workspaces; this state lives in an S3 backend.

terraform_remote_state takes the same config arguments as the backend block, plus an optional workspace argument. Letting the backend resolve the workspace path avoids depending on its storage layout.

Question 3 · choose 1

A team turns on use_lockfile = true for its S3 backend. Plans now fail to acquire the lock, although the role can already read and write the state object itself. Which permissions does the role still need?

  1. Adynamodb:PutItem and dynamodb:DeleteItem on a lock table
  2. Bs3:DeleteObject on the state object itself
  3. Cs3:PutBucketVersioning on the bucket
  4. Ds3:GetObject, s3:PutObject and s3:DeleteObject on the <key>.tflock object
Show the answer and why
  • Adynamodb:PutItem and dynamodb:DeleteItem on a lock table

    Incorrect

    DynamoDB permissions apply to the deprecated table-based locking, not to the S3 lock file.

  • Bs3:DeleteObject on the state object itself

    Incorrect

    Terraform does not delete the state file, so that permission is not needed on it.

  • Cs3:PutBucketVersioning on the bucket

    Incorrect

    Versioning is recommended for recovery but is not a locking permission.

  • Ds3:GetObject, s3:PutObject and s3:DeleteObject on the <key>.tflock object

    Correct

    With use_lockfile set, Terraform creates, reads and deletes a lock file next to the state, so the role needs all three on that object.

S3 native locking writes a .tflock object beside the state. Include it in IAM policies, along with ListBucket on the bucket and read and write on the state object.

Question 4 · choose 1

Following the S3 backend's multi-account pattern, state lives in a bucket in an administrative account, and the AWS provider uses assume_role with role_arn = var.workspace_iam_roles[terraform.workspace] to manage resources in the staging and production accounts. Which identity reads and writes the state?

  1. AThe runner's own credentials in the administrative account
  2. BThe provider's assumed role for the selected workspace
  3. CA role that init derives from the provider configuration
  4. DThe production role for every workspace, as it ranks highest
Show the answer and why
  • AThe runner's own credentials in the administrative account

    Correct

    In this pattern backend operations run as the administrator's own identity in the administrative account, while the provider's assume_role applies only to resource operations.

  • BThe provider's assumed role for the selected workspace

    Incorrect

    assume_role in the provider block is for managing resources; the backend does not use provider configuration.

  • CA role that init derives from the provider configuration

    Incorrect

    init configures the backend from the backend block and the environment, never from provider blocks.

  • DThe production role for every workspace, as it ranks highest

    Incorrect

    Roles have no ranking; the backend uses its own credentials whichever workspace is selected.

Give the administrative identity access to the state and permission to assume the environment roles, and block other access in that account, so a mistake cannot create resources there.

Question 5 · choose 1

A new environment's application configuration reads data.terraform_remote_state.network.outputs.vpc_id, but the network configuration for that environment has not been applied yet, so its state is empty. Which argument lets the application plan with a temporary value?

  1. Aworkspace, set to the name of an empty workspace
  2. Bconfig, with an outputs map added to it
  3. Cdefaults, with placeholder output values
  4. Ddepends_on, pointing at the network configuration
Show the answer and why
  • Aworkspace, set to the name of an empty workspace

    Incorrect

    workspace chooses which state to read; it does not provide missing values.

  • Bconfig, with an outputs map added to it

    Incorrect

    config holds backend settings only; outputs cannot be supplied there.

  • Cdefaults, with placeholder output values

    Correct

    defaults provides values for outputs when the state file is empty or lacks a required output.

  • Ddepends_on, pointing at the network configuration

    Incorrect

    depends_on orders objects within one configuration; it cannot wait for another configuration's apply.

defaults keeps a consuming configuration plannable during bootstrapping, but remember to remove placeholders once the producer exists.

Question 6 · choose 1

An S3 backend still uses dynamodb_table for locking, and some pipelines run older Terraform versions that support only DynamoDB locking. How should the team move to S3 native locking?

  1. AKeep dynamodb_table only, as DynamoDB remains the recommended lock
  2. BSet use_lockfile = true next to dynamodb_table during the transition
  3. CRemove dynamodb_table first, then add use_lockfile after all pipelines upgrade
  4. DReplace both with -lock=false in every pipeline
Show the answer and why
  • AKeep dynamodb_table only, as DynamoDB remains the recommended lock

    Incorrect

    DynamoDB-based locking is deprecated and will be removed in a future minor version.

  • BSet use_lockfile = true next to dynamodb_table during the transition

    Correct

    The S3 and DynamoDB arguments can be configured at the same time to support migration from versions that only know DynamoDB locking.

  • CRemove dynamodb_table first, then add use_lockfile after all pipelines upgrade

    Incorrect

    That leaves runs without any lock during the transition.

  • DReplace both with -lock=false in every pipeline

    Incorrect

    Disabling locking removes protection against concurrent writes.

Run both lock mechanisms during the transition, then drop dynamodb_table once nothing older remains.

Practice domain 2 →Practice all domains →