hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.82k stars 9.16k forks source link

aws_iam_policy_document doesn't honor single-element lists #22322

Open IskanderNovena opened 2 years ago

IskanderNovena commented 2 years ago

Community Note

Terraform CLI and Terraform AWS Provider Version

Terraform v1.1.2
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v3.70.0

Affected Resource(s)

aws_iam_policy_document

Terraform Configuration Files

Please include all Terraform configurations required to reproduce the bug. Bug reports without a functional reproduction may be closed without investigation.

terraform {
  required_version = ">= 1.1.2, < 1.2.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.70.0"
    }
  }
}

provider "aws" {
  region = "eu-west-1"
}

locals {
  test_arns_single = [
    "arn:aws:iam::987654321098:role/SomeRandomRole"
  ]
  test_arns_plural = [
    "arn:aws:iam::987654321098:role/SomeRandomRole",
    "arn:aws:iam::876543210987:role/SomeRandomRole"
  ]
}

data "aws_iam_policy_document" "iam_policy_document_single" {
  version = "2012-10-17"
  statement {
    actions   = ["sts:AssumeRole"]
    effect    = "Allow"
    resources = [for arn in local.test_arns_single : arn]
  }
}

resource "aws_iam_policy" "iam_policy_document_test_single" {
  name = "iam_policy_document_test"
  path = "/"

  policy = data.aws_iam_policy_document.iam_policy_document_single.json
}

data "aws_iam_policy_document" "iam_policy_document_plural" {
  version = "2012-10-17"
  statement {
    actions   = ["sts:AssumeRole"]
    effect    = "Allow"
    resources = [for arn in local.test_arns_plural : arn]
  }
}

resource "aws_iam_policy" "iam_policy_document_test_plural" {
  name = "iam_policy_document_test"
  path = "/"

  policy = data.aws_iam_policy_document.iam_policy_document_plural.json
}

resource "aws_iam_policy" "iam_policy_heredoc_test_single" {
  name = "iam_policy_heredoc_test"
  path = "/"

  policy = <<JSON
{
  "Version": "2012-10-17",
  "Statement": {
    "Action":["sts:AssumeRole"],
    "Effect": "Allow",
    "Resource": ${jsonencode(local.test_arns_single)}
  }
}
JSON
}

resource "aws_iam_policy" "iam_policy_heredoc_test_plural" {
  name = "iam_policy_heredoc_test"
  path = "/"

  policy = <<JSON
{
  "Version": "2012-10-17",
  "Statement": {
    "Action":["sts:AssumeRole"],
    "Effect": "Allow",
    "Resource": ${jsonencode(local.test_arns_plural)}
  }
}
JSON
}

resource "aws_iam_policy" "iam_policy_jsonencode_test_single" {
  name = "iam_policy_jsonencode_test"
  path = "/"

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = {
      Action   = ["sts:AssumeRole"]
      Effect   = "Allow"
      Resource = [for arn in local.test_arns_single : arn]
    }
  })
}

resource "aws_iam_policy" "iam_policy_jsonencode_test_plural" {
  name = "iam_policy_jsonencode_test"
  path = "/"

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = {
      Action   = ["sts:AssumeRole"]
      Effect   = "Allow"
      Resource = [for arn in local.test_arns_plural : arn]
    }
  })
}

output "iam_policy_document_single" {
  value = data.aws_iam_policy_document.iam_policy_document_single.json
}

output "iam_policy_document_test_single" {
  value = aws_iam_policy.iam_policy_document_test_single.policy
}

output "iam_policy_document_plural" {
  value = data.aws_iam_policy_document.iam_policy_document_plural.json
}

output "iam_policy_document_test_plural" {
  value = aws_iam_policy.iam_policy_document_test_plural.policy
}

output "iam_policy_heredoc_test_single" {
  value = aws_iam_policy.iam_policy_heredoc_test_single.policy
}

output "iam_policy_heredoc_test_plural" {
  value = aws_iam_policy.iam_policy_heredoc_test_plural.policy
}

output "iam_policy_jsonencode_test_single" {
  value = aws_iam_policy.iam_policy_jsonencode_test_single.policy
}

output "iam_policy_jsonencode_test_plural" {
  value = aws_iam_policy.iam_policy_jsonencode_test_plural.policy
}

Debug Output

Panic Output

Expected Behavior

The output should be similar for all methods of creating the policy.

Actual Behavior

The output for the aws_iam_policy_document converts single-element lists to a simple string.

Changes to Outputs:
  + iam_policy_document_single        = jsonencode(
        {
          + Statement = [
              + {
                  + Action   = "sts:AssumeRole"
                  + Effect   = "Allow"
                  + Resource = "arn:aws:iam::987654321098:role/SomeRandomRole"
                  + Sid      = ""
                },
            ]
          + Version   = "2012-10-17"
        }
    )
  + iam_policy_document_plural        = jsonencode(
        {
          + Statement = [
              + {
                  + Action   = "sts:AssumeRole"
                  + Effect   = "Allow"
                  + Resource = [
                      + "arn:aws:iam::987654321098:role/SomeRandomRole",
                      + "arn:aws:iam::876543210987:role/SomeRandomRole",
                    ]
                  + Sid      = ""
                },
            ]
          + Version   = "2012-10-17"
        }
    )
  + iam_policy_document_test_single   = jsonencode(
        {
          + Statement = [
              + {
                  + Action   = "sts:AssumeRole"
                  + Effect   = "Allow"
                  + Resource = "arn:aws:iam::987654321098:role/SomeRandomRole"
                  + Sid      = ""
                },
            ]
          + Version   = "2012-10-17"
        }
    )
  + iam_policy_document_test_plural   = jsonencode(
        {
          + Statement = [
              + {
                  + Action   = "sts:AssumeRole"
                  + Effect   = "Allow"
                  + Resource = [
                      + "arn:aws:iam::987654321098:role/SomeRandomRole",
                      + "arn:aws:iam::876543210987:role/SomeRandomRole",
                    ]
                  + Sid      = ""
                },
            ]
          + Version   = "2012-10-17"
        }
    )
  + iam_policy_heredoc_test_single    = jsonencode(
        {
          + Statement = {
              + Action   = [
                  + "sts:AssumeRole",
                ]
              + Effect   = "Allow"
              + Resource = [
                  + "arn:aws:iam::987654321098:role/SomeRandomRole",
                ]
            }
          + Version   = "2012-10-17"
        }
    )
  + iam_policy_heredoc_test_plural    = jsonencode(
        {
          + Statement = {
              + Action   = [
                  + "sts:AssumeRole",
                ]
              + Effect   = "Allow"
              + Resource = [
                  + "arn:aws:iam::987654321098:role/SomeRandomRole",
                  + "arn:aws:iam::876543210987:role/SomeRandomRole",
                ]
            }
          + Version   = "2012-10-17"
        }
    )
  + iam_policy_jsonencode_test_single = jsonencode(
        {
          + Statement = {
              + Action   = [
                  + "sts:AssumeRole",
                ]
              + Effect   = "Allow"
              + Resource = [
                  + "arn:aws:iam::987654321098:role/SomeRandomRole",
                ]
            }
          + Version   = "2012-10-17"
        }
    )
  + iam_policy_jsonencode_test_plural = jsonencode(
        {
          + Statement = {
              + Action   = [
                  + "sts:AssumeRole",
                ]
              + Effect   = "Allow"
              + Resource = [
                  + "arn:aws:iam::987654321098:role/SomeRandomRole",
                  + "arn:aws:iam::876543210987:role/SomeRandomRole",
                ]
            }
          + Version   = "2012-10-17"
        }
    )

Steps to Reproduce

  1. terraform plan A 'plan' is enough to show the differences without actually deploying stuff.

Important Factoids

References

github-actions[bot] commented 9 months ago

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

IskanderNovena commented 9 months ago

Is this still on the radar?