Score:1

Why does Terraform want to fully delete aws_iam_policy_document?

sm flag

I don't understand why Terraform wants to remove the json policy. In other cases, when the data will be read during the apply, the plan shows the json policy being removed and added in the same plan, but it is not happening, Terraform is just removing it.

This is the policy:

data "aws_iam_policy_document" "my_policy" {
  statement {
    sid = "S3"
    effect = "Allow"
    actions = ["s3:*"]
    resources = [
      aws_s3_bucket.some-bucket.arn,
      "arn:aws:s3:::another-bucket/*",
      "arn:aws:s3:::another-bucket/"
    ]
  }
  statement {
    sid = "CloudWatch"
    effect = "Allow"
    actions = ["logs:*"]
    resources = [
      aws_cloudwatch_log_group.some_lambda.arn,
      "arn:aws:logs:us-east-1:123456789123:log-group:/some/log/group:*",
      "arn:aws:logs:us-east-1:123456789123:log-group:/some/log/group"
    ]
  }
}

And here is plan:

  # data.aws_iam_policy_document.my_policy will be read during apply
  # (config refers to values not yet known)
 <= data "aws_iam_policy_document" "my_policy"  {
      ~ id      = "123456789" -> (known after apply)
      ~ json    = jsonencode(
            {
              - Statement = [
                  - {
                      - Action   = "s3:*"
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:s3:::another-bucket/*",
                          - "arn:aws:s3:::another-bucket/",
                        ]
                      - Sid      = "S3"
                    },
                  - {
                      - Action   = "logs:*"
                      - Effect   = "Allow"
                      - Resource = [
                          - "arn:aws:logs:us-east-1:123456789123:log-group:/some/log/group:*",
                          - "arn:aws:logs:us-east-1:123456789123:log-group:/some/log/group",
                        ]
                      - Sid      = "CloudWatch"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
      - version = "2012-10-17" -> null

      ~ statement {
          - not_actions   = [] -> null
          - not_resources = [] -> null
          ~ resources     = [
              + "arn:aws:s3:::some-bucket/",
                # (2 unchanged elements hidden)
            ]
            # (3 unchanged attributes hidden)
        }
      ~ statement {
          - not_actions   = [] -> null
          - not_resources = [] -> null
            # (4 unchanged attributes hidden)
        }
    }

1 - Why Terraform wants to wipe out this json policy?

2 - The not_actions and not_resources are optional. I thought it will not appear in the plan. Is this normal?

Score:1
ph flag

What Terraform has described here is not to delete the policy JSON, but to update it in place:

  ~ json = jsonencode(...) -> (known after apply)

Notice that the annotation on the whole attribute is ~, rather than -, which means that it's being updated in place.

The (known after apply) part of this is the interesting part: it's telling you that Terraform doesn't yet know what the final policy document JSON will be. That typically happens if any of the values that are contributing to the document are values that won't be known until the apply step, which is what the note at the top of the plan is trying to say:

  # (config refers to values not yet known)

During the apply phase Terraform will again try to evaluate this data resource, at which point all of the values should be known and so it will be able to read it. It should then produce a valid policy document to use, which will probably be similar to the old one but Terraform itself doesn't know that yet.

If you want to see the new policy in full before you apply it to any other resources then you could use the -target option to ask Terraform to focus only on making the changes that will allow deciding the JSON document, like this:

terraform apply -target=aws_s3_bucket.some-bucket.arn -target=aws_cloudwatch_log_group.some_lambda.arn

With those -target options Terraform will skip planning the data resource and anything else that depends on it, and so you won't see any mention of data "aws_iam_policy_document" "my_policy" in the plan. Once you've applied that partial change, you can then run terraform apply without any arguments as normal and then Terraform should be able to evaluate the JSON policy document during the planning phase, because all of the input values will already be known.


The changes from [] -> null for those not_actions and not_resources arguments seem to just be minor bugs in the provider: the provider seems to be inconsistent about whether unset is represented as an empty list or as null, and so Terraform CLI is rendering that difference on-screen. The provider ought to be consistent about how it represents that to avoid showing this confusing extra noise.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.