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
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?
APass a fresh -backend-config token from the job's environment to terraform apply tfplan
BRun terraform init -reconfigure in the apply job before applying the saved plan
CStore the token in the backend block itself to have plan and apply always read exactly the same value
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.
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?
Abackend = "s3" and key = "${terraform.workspace}/network/terraform.tfstate" in the config object
Bbackend = "s3" and workspace_key_prefix = terraform.workspace in config
Cbackend = "s3", the same bucket, key and region in config, and workspace = terraform.workspace
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.
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?
Adynamodb:PutItem and dynamodb:DeleteItem on a lock table
Bs3:DeleteObject on the state object itself
Cs3:PutBucketVersioning on the bucket
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.
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?
AThe runner's own credentials in the administrative account
BThe provider's assumed role for the selected workspace
CA role that init derives from the provider configuration
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.
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?
Aworkspace, set to the name of an empty workspace
Bconfig, with an outputs map added to it
Cdefaults, with placeholder output values
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.
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?
AKeep dynamodb_table only, as DynamoDB remains the recommended lock
BSet use_lockfile = true next to dynamodb_table during the transition
CRemove dynamodb_table first, then add use_lockfile after all pipelines upgrade
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.