cswork / libraryOpen practice workspace

Articles

Terraform Secrets Interview Questions: Sensitive Values, State, and Ephemeral Data

Practice Terraform secret-handling interview questions with redaction versus state persistence, ephemeral values, write-only inputs, and rotation decisions.

An interviewer shows you a Terraform plan that prints (sensitive value) for a database password and asks, “Is this secret now safe?” The useful answer is no: redaction and persistence are different controls. You need to trace where the value enters Terraform, whether it lands in plan or state, who can read those artifacts, and whether the provider has a write-only path. Saying “mark it sensitive” only addresses one visible symptom.

This guide uses HashiCorp's current sensitive-data guidance for Terraform behavior. The sample infrastructure and questions are original interview exercises, not candidate reports or claims about a particular employer's interview. For adjacent practice, Discuss Terraform, Infrastructure as Code, and AWS Experience asks you to connect state to a real change you owned.

Question 1: What does sensitive = true actually protect?

It marks a value as sensitive so Terraform redacts it in ordinary CLI output and in many UI displays. It propagates sensitivity through expressions, which can prevent accidental display of a derived value. It does not mean the value is encrypted by Terraform everywhere, absent from the plan, or omitted from state. HashiCorp explicitly distinguishes display redaction from storage: sensitive input values and resource attributes can still be present in state and plan files. A saved plan therefore needs the same access controls as state when it carries secrets.

The interviewer may ask whether terraform output -json is safe because the terminal printed a mask. It is not a safe inference. HashiCorp documents that terraform output -json and -raw can reveal sensitive output values. Likewise, a provider or external command may log input at its own boundary. Avoid making a blanket promise about every log and plugin; name the specific artifact you checked and the access path you controlled.

A strong answer describes an information flow. Secret enters through a variable, is consumed by a resource argument, and might be returned in resource state. sensitive = true changes display handling; it does not erase that flow. Put remote state behind least-privilege access, encryption and locking supported by the chosen backend, restrict plan artifacts and CI logs, and rotate a credential if it was exposed. Where possible, use a data path that avoids persistence rather than treating state encryption as a substitute.

Question 2: When would you use an ephemeral value?

Terraform 1.10 added ephemeral values for selected contexts. An ephemeral input variable or supported ephemeral block can be used during a run without being stored in state or plan. That is a materially different claim from sensitive: the value is omitted from those artifacts, not merely masked in a normal display. HashiCorp limits where ephemeral values may flow, because a persistent resource argument or output cannot quietly depend on something Terraform will be unable to recall at a later plan.

Ask the interviewer where the value is needed. A short-lived authentication token used to configure a provider during the run is a plausible ephemeral input. A password that a managed resource persists as an ordinary argument is not magically made ephemeral just because its source variable is. If the destination requires a lasting value in state, Terraform will restrict the flow or the provider will need a purpose-built write-only argument. The distinction matters more than memorizing syntax.

For a hypothetical deployment, consider variable "session_token" { type = string; ephemeral = true; sensitive = true }. This describes a run-scoped token supplied securely to an allowed consumer. It does not prove the provider itself never logs the token or the remote API never stores it. The security claim is narrow: Terraform omits an ephemeral value from its state and plan. Check the exact Terraform version and the receiving block's documented support before offering this as a fix.

Question 3: What is a write-only argument, and what is its limit?

Terraform 1.11 introduced write-only resource arguments as an option when the provider exposes one. Terraform can pass a secret to the provider without persisting that argument's value in plan or state. The provider's schema and implementation decide which resource arguments support this behavior. You cannot turn an arbitrary password argument into a write-only one by renaming a variable or adding sensitive = true.

This creates an interview-worthy update problem. If Terraform does not retain the secret, how will it detect that the desired secret changed later? Provider designs may use an explicit version or rotation trigger alongside a write-only argument. The exact convention is resource-specific, so read the provider documentation rather than inventing a universal _wo_version field. Explain what should happen when the credential rotates, how the service rolls over clients, and how you would verify the change without reading the secret back into Terraform state.

An external secret manager is another boundary. Sometimes Terraform should provision the reference and access policy while the workload obtains the secret at runtime. That may reduce secret exposure through Terraform artifacts. It also moves availability, permission, audit, and rotation responsibilities to the runtime path. It is a design choice, not a guarantee that no secret exists anywhere. A good candidate asks whether Terraform needs the secret bytes at all.

A secret-path decision table

The following table is an editorial decision aid derived from HashiCorp's documented distinctions. It is not a ranking that applies to every provider. Follow the actual secret through the provider and backend before asserting an outcome.

MechanismWhat it changes in TerraformWhat you must still verify
sensitive = trueRedacts normal display and marks derived expressions sensitiveState and saved plan access; raw/JSON outputs; provider logging
Ephemeral variable or blockOmits supported run-scoped values from plan and stateTerraform version; permitted context; downstream consumer behavior
Provider write-only argumentPasses a supported value without persisting that argumentProvider version/schema; change detection and rotation trigger
Runtime secret referenceKeeps Terraform focused on a reference or policyWorkload identity, manager availability, audit and rotation

Try the table on a concrete scenario: a CI pipeline sets TF_VAR_db_password, runs terraform plan -out=plan.bin, uploads plan.bin for approval, then runs apply. If the only control is a sensitive variable, the approver may see a redacted diff, but the plan artifact still needs restricted storage and retention. If the provider supports a write-only password argument and the configuration uses an allowed ephemeral source, the artifact exposure can be reduced. The team must then design rotation and verification. This is an inference from the documented data paths, not a claim that every database provider supports that combination.

Question 4: How do you secure state without pretending it is secret-free?

Treat state as a potentially sensitive operational record. Choose a backend with access control appropriate to the team, encryption at rest and in transit, and controlled backups. Restrict both read and write permissions: read access can reveal secret material, while write access can corrupt resource tracking or redirect changes. Locking prevents concurrent applies from colliding, but it is not a confidentiality feature. A candidate should explain both risks separately.

Review where state goes during CI, local troubleshooting, backups, and incident response. A local terraform.tfstate in a developer home directory is a different exposure path from a managed remote backend, but either can be copied into a ticket or attached to a chat. Avoid terraform state pull as casual debugging when a targeted plan or provider API query would answer the question. If you must inspect it, use a restricted environment and avoid pasting output into a broad channel.

The state access boundary is also where an interviewer may test whether you understand drift. Terraform needs state to compare previously managed objects with configuration and provider reality. Deleting a leaked state file is not a clean repair: it can make Terraform forget resources and plan duplicate creation. Contain exposure, rotate the affected secret, assess backups and copies, and plan any state repair with exact resource addresses and reviewed backups. This is an operational recommendation, not an assertion that Terraform automatically recovers after rotation.

Question 5: What if a secret appears in a plan or log?

First identify which artifact contains the bytes and how it was distributed. A redacted terminal screenshot, a binary saved plan, a CI log from a shell trace, and a provider HTTP debug log have different audiences and retention. Stop the leak path and restrict or remove exposed copies under your organization's incident process. Rotate the credential if exposure is plausible, then verify that old credentials fail and new clients can authenticate. Do not assume deleting one CI job erases an artifact from backups.

Next fix the root cause. If a shell used set -x, turn off tracing around secret handling. If a script echoed a variable, stop printing it. If an output deliberately exposed a secret, question why that output exists and whether an ephemeral output or external runtime delivery is more appropriate. If the plan artifact is required for approval, manage it as secret-bearing data. If provider logging printed it, investigate the provider's debug settings and supported input options. A candidate should not claim that sensitive = true scrubs text already emitted by an external program.

Close with a testable control: a fresh run on the pinned Terraform/provider versions, an audit of who can fetch state and plan artifacts, and a rotation exercise. The test should use a disposable credential, not a production secret pasted into an interview demo. Record exactly what did and did not appear in normal CLI output, saved plans, state, and provider logs.

Question 6: What answer would you give in two minutes?

“I would separate display redaction from persistence. sensitive = true masks ordinary CLI output but can leave the bytes in state and a saved plan. I would ask whether Terraform actually needs the secret, whether this Terraform version supports an ephemeral source, and whether the selected provider exposes a write-only destination. I would restrict state and plan access regardless, then test rotation and verify the old credential is invalid. I would not promise that a provider or CI step cannot log a value without checking that boundary.”

That answer is stronger than “put secrets in Vault” because it names the data path and the remaining operational work. It also keeps the scope honest: these are original practice prompts, and HashiCorp's docs establish product behavior; they do not establish that any company asks this exact question. If your example is from work, state the Terraform/provider versions and what you personally observed rather than borrowing an incident you did not handle.

Each is an adjacent exercise, not a claim that it covers Terraform's ephemeral syntax directly.

Practice questionConnection to this scenario
Discuss Terraform, Infrastructure as Code, and AWS ExperienceExplain state access and a reviewed infrastructure change.
Design Safe Configuration and Deployment for Hundreds of ServicesDesign controlled delivery of sensitive configuration.
Design a configuration subscription serviceDecide whether runtime clients should fetch a reference or value.
Present Your Infrastructure and Platform ExperienceDescribe a secret-handling decision you actually owned.
Describe leading an infrastructure initiativeExplain how access and rotation became an operational contract.

Continue with Terraform interview questions for platform engineers and rehearse one resource from input to provider, state, plan, CI artifact, and runtime consumer. The correct control depends on that path.

Sources and further reading