TL;DR: Marking a variable sensitive blurs CLI output and nothing else: ordinary persisted values can still land in state and saved plans. Ephemeral values and provider-supported write-only arguments are explicit exceptions. Real handling pulls secrets from a manager at apply time, prefers write-only arguments that skip state entirely, encrypts and ACLs the backend, and treats a state read as credential exposure requiring rotation.
How to approach it
Answer as a threat walk: follow the value through git, CI, plan, state, and the provider side, naming the control at each hop. Precision about what sensitive does and does not do is exactly the line interviewers probe.
A strong answer
Map the leaks first. Git history: tfvars with literals committed "for bootstrap" outlive every rotation that forgot them. CI logs: variable values echoed by plan, or worse, interpolated into a resource name or tag where they print in every future diff. Plan artifacts: saved plans and their JSON exports embed values, and artifact retention in most CI systems is measured in weeks. State: ordinary resource and data-source attributes are recorded and readable with backend access. Provider side: inspect API logging and secret-manager storage too. A database may store a password verifier rather than retrievable plaintext; do not assume its console or snapshots expose the original password.
The controls, in the order they pay off:
Keep the entire secret path ephemeral where supported. An ordinary secrets-manager data source persists its result even when the destination uses password_wo. This partial resource example requires Terraform 1.11 or later and an AWS provider version supporting both the ephemeral source and write-only destination:
ephemeral "aws_secretsmanager_secret_version" "db" {
secret_id = "prod/payments/db-master"
}
resource "aws_db_instance" "core" {
# Other required DB arguments omitted; secret_string is the password here.
password_wo = ephemeral.aws_secretsmanager_secret_version.db.secret_string
password_wo_version = 7
}
The source is read during the operation when needed, potentially in both plan and apply. Coordinate the secret version with password_wo_version: Terraform cannot compare an omitted password to detect rotation. HashiCorp’s ephemeral-value guide shows this source-to-destination pattern.
Use sensitive honestly. sensitive = true on variables and outputs prevents display in CLI output and blocks naive logging; it changes storage nowhere. It also propagates through derived values, which occasionally frustrates (a sensitive value cannot serve as a for_each key) and is otherwise correct.
Prefer ephemeral and write-only paths where supported. Current Terraform offers ephemeral values that exist only during a run, and write-only resource arguments that providers transmit without recording. Where the provider supports them, the secret skips state altogether, the largest single improvement in Terraform secret handling in years, and worth naming unprompted.
Harden state as the fallback. Backend encryption enforced, bucket policy tighter than the secrets manager's own read path, versioning on, access logged. OpenTofu ships client-side state encryption natively; with Terraform the backend controls are the control. Anyone reading exposed state versions can recover persisted secrets. Inventory those versions and revoke or rotate credentials that may remain usable; existing short-lived values may already have expired.
Close the pipeline holes. CI authenticates to the secrets manager via OIDC federation instead of long-lived keys; plan artifacts are encrypted and expire in days; gitleaks or equivalent runs in pre-commit and CI; tfvars files ship as templates with placeholders, never values.
What interviewers probe next
"Why not encrypt tfvars in git with SOPS?" Key management becomes commits, rotation means history archaeology, and access is repo-grained rather than secret-grained. A secrets manager gives TTLs, audit trails, and dynamic credentials; encrypting files solves storage while leaving distribution broken.
"State was exposed. Walk me through the response." Treat it as credential compromise: enumerate every secret the state versions contained, rotate them, audit access logs to bound the window. Deleting the file says nothing about what was already read.
"Static rotation or dynamic credentials?" Dynamic short-lived database credentials delete the rotation plumbing where workloads tolerate them; otherwise provider-managed rotation beats cron jobs and runbooks.
Common mistakes
Believing sensitive = true secures storage, then publishing state to a wide-read bucket.
Interpolating a secret into a tag or name "temporarily", which prints it in every subsequent plan and in the console forever.
Rotating the secret in the manager while Terraform still pins the old value, so the next apply quietly reverts the database password and locks the application out.