Determining whether a value is known at plan-time

Viewed 58

Terraform allows values to be marked as "unknown" during the plan step, since many values may only be known after apply of certain resources.

Is there any way, during the plan step, to check if a value is known or unknown?

Specifically, I'd like to be able to do something like this:

locals {
  foo = "hello world"
  bar = uuid()
}

output "foo_known" {
  value = knownatplan(local.foo)
}

output "bar_known" {
  value = knownatplan(local.bar)
}
Outputs:

foo_known = true
bar_known = false

Where knownatplan would be a function, or some sort of other mechanism, to determine if the value is known at plan time.

2 Answers

There is no mechanism to do this because to do so would break an assumption that Terraform relies on to do its work: that replacing unknown values with known values during the final apply step can only add information, never change information. The above guarantee is fundamental to the concept of planning a change before taking any side-effects.

Other systems whose language doesn't have this mechanism can only provide a hypothetical "dry run" of changes that may not be complete or accurate, whereas Terraform aims to make the additional promise that it will either make the changes as shown in the plan or return an error explaining why it cannot. Any situation where applying the plan succeeds but generates a result other than what the plan reported is always considered to be a bug, either in Terraform Core itself or in the relevant provider. Unknown values are a big part of how Terraform keeps that promise.

I wrote about this in more detail in a blog article Unknown Values: The Secret to Terraform Plan.

I had a little bit time now, and could implement a cool "feature" the inventors of terraform would not much like. ^-^

I am author of terraform-provider-value (github) (terraform registry) and there I have two resources called value_is_fully_known (link) and value_is_known (link). Sounds good? Just look look in the documentation or look here for some examples.

Fundamentally they allow you to have a true or false for a value that might be "(known after apply)" before you actually apply! Here an example:

terraform {
  required_providers {
    value = {
      source  = "pseudo-dynamic/value"
      version = "0.5.1"
    }
  }
}

locals {
  foo = "hello world"
  bar = uuid()
}

resource "value_unknown_proposer" "default" {}

resource "value_is_known" "foo" {
  value            = local.foo
  guid_seed        = "foo"
  proposed_unknown = value_unknown_proposer.default.value
}

resource "value_is_known" "bar" {
  value            = local.bar
  guid_seed        = "bar"
  proposed_unknown = value_unknown_proposer.default.value
}

output "foo_known" {
  value = value_is_known.foo.result
}

output "bar_known" {
  value = value_is_known.bar.result
}

which results into:

Outputs:

bar_known = false
foo_known = true

Before actual apply?

Concretely you are running through two plan-phases, one I call plan-phase and the other one I call apply-phase, which includes another, independent and implicit plan-phase. The plan-phase is characteristical when you see the plan, the potencial results (most of the times with a lot of "known after apply"-values") and the message "Terraform will perform the following actions:". The apply-phase on the other side is, when all values are calculated in the view of the provider author, terraform or you when you see "Apply complete!".

It was very challenging to implement an acceptable solution because during the plan-phase the provider has no chance to to save anything because nothing is persistent. Only changes in the implicit plan-phase are stored when apply-phase was successful.

My thoughts

To know before you apply whether a value is known or unknown, can enable you some cool workflows in terraform but they should be very limited. I can only encourage you to use this mechanism as rarely as possible. But if you have some cool usages for it, do you mind to share them? Feel free to open pull request to add an example or begin a discussion.

Any form of feedback (constructive critism, bugs and ideas) I appreciate a lot. =)

Related