skip to content

Unknown Until Apply

A value the plan cannot know yet is neither compliant nor violating, so one rule can silently wave through a public bucket or block a safe one. This is where naive gates fail open.

on this pageshow

questions

3

In a Terraform plan, what does an attribute marked "known after apply" mean for a policy rule?

level: juniorimportance: must knowfreq 68%

answer

  1. the plan does not have the value yet
  2. the provider computes it at creation
  3. prints as known after apply
  4. a separate map marks the unknown paths
  5. empty and unknown are different states

basics

~20 s

It means the value does not exist yet: the provider or cloud only produces it when the resource is actually created, so the plan holds a placeholder. A policy rule evaluating that attribute has nothing real to test.

solid answer

~50 s

It means the value cannot be computed while the plan is being made — the provider or the cloud only assigns it at creation time — so the plan records a placeholder instead of a value. In the JSON plan the attribute carries no real value in the `after` object and the corresponding path is marked in `after_unknown`; the human-readable plan prints `(known after apply)`. For a policy gate that is a hole, not a value: there is nothing to compare against, and nothing elsewhere in the plan reveals what it will become. The practical consequence is that a rule has to handle three cases, not two — the attribute is set to something, the attribute is genuinely unset, or the attribute is unknown. A null in `after` on its own does not tell you which of the last two you are looking at.

go deeper

for a junior

Be ready to say plainly that the value does not exist yet, that the plan holds a placeholder, and to point at where a plan shows that. Knowing one concrete example, such as an ARN for a resource being created, is enough.

for a middle

Explain how the JSON plan records it — no usable value in the after object, the path flagged in the unknown map — and why an unknown attribute is a different state from an attribute nobody configured.

for a senior

Show that you check how often your rules actually meet unknowns in real plans, and that you treat a rule never tested against an unknown as a rule you have not tested.

for a principal

Own the consequence: some controls simply cannot be preventive at plan time, so decide which of them the organisation enforces later and who carries that.

## The short version An infrastructure-as-code plan is a description of a change that has not happened yet. Some attributes of that change can be worked out in advance — anything written literally in the configuration, or derived from values already in state. Others cannot, because the value is produced by the cloud provider at the moment the resource is created. Those attributes are marked *unknown*, and the human-readable plan prints them as `(known after apply)`. ## Where unknown values come from The common sources are worth being able to list, because they predict which of your rules will run into them: - **Identifiers assigned at creation.** ARNs, resource IDs, generated DNS names, allocated IP addresses. Nothing on your side can compute these; the provider learns them from the API response. - **Values derived from something that does not exist yet.** If an attribute is set from another resource that this same change is creating, the source value is unknown, so the destination attribute is unknown too. - **Values produced during apply.** Generated passwords and keys, timestamps, anything a provider computes rather than reads. - **Lookups deferred to apply.** If a data lookup cannot be resolved while planning, everything downstream of it is unknown. A useful corollary: unknowns are densest on a **first apply**, when everything is being created. Re-planning the same configuration later, against state where those resources already exist and are not changing, usually shows the same attributes as concrete values. ## How the plan writes it down In the JSON plan representation, each resource change carries a `before` object, an `after` object, and an `after_unknown` object. `after_unknown` mirrors the shape of the resource and marks the paths whose values are not yet known. The attribute itself does not carry a usable value in `after`. So the plan is honest about its own incompleteness — but only if you read the marker. This is the one document shape in a policy pipeline that is deliberately partial, and a rule that reads only `after` sees a gap without being told it is a gap. ## Unknown is not null, and not sensitive Two distinctions trip people up: - **Unknown versus unset.** An optional attribute nobody configured is empty because there is nothing to configure. An unknown attribute is empty because the answer does not exist yet. Reading `after` alone, both can look the same; only the unknown marker separates them. The difference matters enormously for policy: "nobody set an encryption key" is often a real violation you want to report, while "the key identifier is not computable yet" is a case you could not evaluate. - **Unknown versus sensitive.** Sensitivity is about whether a value should be displayed; it is tracked separately from whether the value is computable. A value can be perfectly well known and still marked sensitive. Do not conflate "I cannot see it" with "it does not exist yet." ## What this means for a rule Three consequences follow, and they are the whole reason this concept appears in interviews: 1. **You cannot test the value.** No comparison, pattern match or set membership over an unknown attribute produces a meaningful result, because there is no value under it. 2. **You cannot recover it later in the same document.** The plan will not tell you what the value becomes. Waiting, re-reading, or looking in another section does not help — the information is not in the artifact. 3. **You must choose a posture.** Because the rule cannot decide on the merits, someone has to decide what an unevaluable attribute means: block the change, warn, record it for a later check, or accept it. Silence is also a choice, and it is the one that produces a green pipeline for a change nobody checked. ## What to say in an interview Say that the value does not exist yet and the plan admits it; say where the plan admits it; and say that a gate therefore has to treat unknown as its own case rather than as an empty value. If you can add that unknowns are concentrated on first creates and thin out on later runs, you have shown you have actually looked at real plans rather than only read about them.

  • Name two common reasons an attribute is unknown at plan time.
    Identifiers the cloud assigns at creation — ARNs, resource IDs, allocated addresses — are unknown for anything the change is creating. So are values produced during the apply itself, such as a generated password, or anything derived from a resource that does not exist yet. On a later run against existing state, those same attributes are usually concrete.
  • How does an unknown attribute differ from one that is null because nobody set it?
    In the JSON plan both can look empty in the `after` object. Only the unknown marker separates them: it flags the path as not-yet-computable, while a genuinely unset optional attribute is simply empty with no such flag. The distinction matters because "not set" is usually a finding you want to report, whereas "unknown" means the rule could not check.
  • Can the policy engine fetch the real value from the cloud instead?
    Not for a resource that does not exist yet — there is nothing to query. For resources that already exist you could query them, but that is a different control running at a different time against live state, not a plan-time gate. Conflating the two is how teams end up believing a pre-merge check verified something it never saw.

It is like reviewing a contract where the price reads "to be determined at signing". You can insist on a cap in advance, but you cannot check the number today.

saying these in an interview costs you the question

  • Says the engine can simply re-read the value from the cloud
  • Treats an unknown attribute as though it were empty or unset
  • Assumes the value appears somewhere else in the plan file
  • Thinks the value is hidden only because it is sensitive
  • Believes unknowns appear equally on every run

context

open as a page

Why does a rule denying deprecated TLS policies quietly pass a listener whose value is unknown until apply?

level: middleimportance: must knowfreq 52%

basics

~20 s

A value that does not exist matches nothing. The rule hunts for a forbidden TLS policy, finds no value at all under that attribute, and reports no violation — a pass that looks identical in CI to a genuine one.

open as a page

Your encryption-at-rest rule reads a key ARN unknown until apply: block, defer, or constrain the input?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Decide per control, not globally: blocking every unknown is safest but taxes teams with failures they cannot act on, deferring the assertion leaves a window where non-compliant infrastructure exists, and constraining the module input removes the unknown wherever you own the code.

open as a page