A Terraform module generates a database password with `random_password` and exposes it as an output so operators can retrieve it. Trace where that value ends up, and say what marking the output sensitive does and does not change.
answer
- follow the value, not the flag
- generated on the apply machine
- logs are the leak that outlives rotation
- redaction closes one door of several
- export the identifier, not the secret
basics
~20 sThe value lands in the plan and apply logs, in state, and in anything reading terraform output. Marking the output sensitive removes it from Terraform's own display only; state still holds it in plain text and terraform output -json still prints it. Prefer writing it to a secret store and exporting only its identifier.
solid answer
~50 sTrace it honestly: `random_password` computes the value during apply, so it exists in the provider's plan data, in the state file in clear text, in the apply summary and any CI job log that captured it, in whatever resource consumed it, and in every later `terraform output`. Marking the output `sensitive = true` closes exactly one of those doors — Terraform's own rendering — which matters, because a CI log is readable by everyone with repo access and outlives the credential. It closes none of the others: state is still plaintext (protecting state is a backend concern of its own), `terraform output -json` still prints the value by design, and provider or `TF_LOG` debug output can still expose it. The senior answer is to change the shape: have Terraform write the generated secret into a secret manager and export only the secret's identifier, so nothing downstream needs the plaintext to leave the apply.
code
hcl · 18 linesresource "random_password" "db" {
length = 32
}
resource "aws_secretsmanager_secret" "db" {
name = "app/db/password"
}
resource "aws_secretsmanager_secret_version" "db" {
secret_id = aws_secretsmanager_secret.db.id
secret_string = random_password.db.result
}
# Export the reference, not the value: this output is not sensitive,
# and the application resolves the secret at runtime with its own role.
output "db_password_secret_arn" {
value = aws_secretsmanager_secret.db.arn
}go deeper
Be able to say that a generated password appears in the apply output and in the state file, and that sensitive = true stops Terraform from printing it.
Trace every location the value reaches — plan data, state, the consuming resource, the CI log, terraform output — and state precisely which single one the sensitive flag closes.
Show operational judgment: name the CI log as the leak that outlives rotation, insist on an encrypted access-controlled backend, and reshape the module to export a secret identifier rather than the plaintext.
Set the organisational default. Decide whether Terraform may generate and hold credentials at all, mandate the secret-store-plus-identifier pattern, and back it with policy checks so a plaintext-bearing output cannot merge unnoticed.
## Trace the value, do not argue about the flag The interviewer is testing whether you can follow a secret through a system rather than recite what `sensitive = true` does. Follow it. 1. **Generation.** `random_password` is computed by the provider during apply — the value is created on the machine running Terraform. 2. **State.** Every attribute of a managed resource is recorded, so `random_password.db.result` is written into the state file in clear text. So is the output that exports it. This is unconditional: the sensitive mark stores a flag beside the value, not instead of it. 3. **Consumers.** Whatever resource takes the password — a database instance, a Kubernetes secret, a parameter — holds it in its own state entry too. 4. **Terminal and CI log.** Without a sensitive mark, the value renders in the apply summary and in any plan diff that includes the output. In CI that means a job log, usually retained for months and readable by everyone with access to the repository. 5. **Retrieval.** Anyone who can run `terraform output -json`, or read the state file, gets the value. ## What the flag closes `sensitive = true` on the output redacts step 4, and propagates so that derived expressions cannot leak it either. Do not undersell this: log exposure is the most common real-world leak, because logs are copied into tickets, pasted into pull requests, and retained long after the credential rotated. Closing it is worth doing on every secret-bearing output. ## What the flag does not close Steps 2, 3, and 5 are untouched. State holds the plaintext, and the controls for that are backend-level — encryption at rest, a tightly scoped access policy, versioning, and never committing state — a topic in its own right, but the point here is that the output flag is not a substitute for any of it. `terraform output -json` and `-raw` print sensitive values deliberately, so a pipeline step that dumps outputs to an artifact re-opens the log path the flag just closed. And a provider that logs a request body, or `TF_LOG=DEBUG`, prints whatever it was handed. ## The design answer Once you have traced it, the real question is whether the plaintext should traverse Terraform's data path at all. Better shapes, roughly in order of preference: **Terraform creates the secret, the secret store holds it, the output is only an identifier.** Generate with `random_password`, write it into a secret manager resource, and export the secret's ARN, ID, or name. The identifier is not sensitive, so the plan reads normally, and the consumer resolves the value at runtime with its own credentials. The plaintext is still in state — that is unavoidable when Terraform generated it — but nothing downstream needs it to leave the apply. **Terraform never sees the secret.** Have the platform generate and manage it (a managed-rotation secret, a service-linked credential) and let Terraform reference it. Nothing sensitive enters state at all. This is the strongest option when the provider supports it. **The consumer reads it directly.** The application fetches from the secret store at boot instead of receiving the value through configuration. Terraform then wires up permissions, not credentials. Terraform 1.10 also added `ephemeral = true` for values that must not be persisted: an ephemeral output is not written to state and can only be consumed by a parent module, never read back with `terraform output`. It narrows the surface for values passed between modules, but it does not retroactively fix a resource attribute that state already records. ## Rotation is the tell The follow-up that separates candidates: if this password leaks, what do you do? With the value spread across state history, log archives, and build artifacts, rotation means changing it *and* accepting that old copies exist in immutable places. With a secret-store shape, rotation is a single write plus a consumer refresh, and there is no log to purge. Designing so that the blast radius of a leak is small is more valuable than any redaction flag. ## Reviewing it Ask: is every secret-bearing output marked sensitive; is the state backend encrypted and access-controlled; does any pipeline step run `terraform output -json` or archive outputs; is `TF_LOG` ever enabled in CI; and could this output be an identifier instead of a value. Answering the last one "yes" makes the other four much less load-bearing.
- If the pipeline must hand this password to another system, how do you do it without widening exposure?Write the secret into a secret store from Terraform and grant the consuming system read access, so it fetches at runtime and the pipeline never holds the plaintext. If a value must pass through CI, fetch exactly that one output by name, keep it in a variable rather than a file, register it with the CI masking mechanism, and never archive it.
- This secret leaked into a CI log six months ago. What does remediation look like?Rotate first — assume disclosure and replace the credential everywhere it is used. Then reduce recurrence: mark the output sensitive, purge or expire the log retention where you can, and move to a shape where the plaintext never renders. Old logs and old state versions are often immutable, which is precisely why the design fix matters more than the redaction.
- Does marking the output sensitive change anything about the plan diff for the resource itself?No. The provider already marks `random_password.result` sensitive in its schema, so that attribute renders as `(sensitive value)` in the resource diff regardless of your output. The output flag governs only the output's own rendering — which is why you still need it even when the source attribute is already marked.
saying these in an interview costs you the question
- Says marking the output sensitive means the password is now secure
- Assumes the value is not in state because the output is sensitive
- Forgets that CI job logs persist far longer than the credential
- Proposes terraform output -json in CI to hand the secret onward
- Treats Terraform outputs as a substitute for a secret manager