How to avoid '-> (known after apply)' on Terraform

Posted: April 12, 2021


tl;dr

Don’t use resources result value directly, but use local variables.

Example

resource "aws_s3_bucket_policy" "foobar" {
  bucket = aws_s3_bucket.foobar.bucket
  policy = data.aws_iam_policy_document.s3_foobar.json
}

data "aws_iam_policy_document" "s3_foobar" {
  version = "2008-10-17"

  # require SSE-KMS
  statement {
		# (omit ...)
    resources = [
      # "${aws_s3_bucket.foobar.arn}/*",  # <-- Don't use other resource results directly!
			"${local.aws_s3_foobar_arn}/*",     # use local variables
    ]
		# (omit ...)
  }
}

locals {
  aws_s3_foobar_arn = aws_s3_bucket.foobar.arn
}

Problem

Whenever I did terraform plan or terraform apply without any changes, some resources seemed that they were changed and shows -> (known after apply) , especially on aws_iam_policy_document.

The answer is from here.

https://github.com/hashicorp/terraform/issues/27282

If we use the value via local variables, then the value acts like ‘wait’ and do not ‘defer’ the actual values.