Search code examples
jsonterraformamazon-iamterraform-provider-aws

Trying to create an IAM policy with terraform getting a syntax error but cant see it


I am extending the power user role with multiple data "aws_iam_policy_document" items:

data "aws_iam_policy" "policy_poweruser" {
  arn = "arn:aws:iam::aws:policy/PowerUserAccess"
}

data "aws_iam_policy_document" "poweruser_extended_passrole" {
  source_policy_documents = [data.aws_iam_policy.policy_poweruser.policy]
  statement {
    sid       = "passec2basic"
    effect    = "Allow"
    actions   = ["iam:passrole"]
    resources = ["arn:aws:iam::238423423:role/ec2_basic"]
  }
}

data "aws_iam_policy_document" "poweruser_extended_prod" {
  source_policy_documents = [data.aws_iam_policy_document.poweruser_extended_passrole.json]
  statement {
    sid       = "environmentaccess"
    effect    = "Allow"
    actions   = local.gated_actions
    resources = ["*"]
    condition {
      test     = "stringequals"
      variable = "aws:resourcetag/environment"
      values   = ["prod"]
    }
  }
}

What it comes out to in terraform plan is

 + policy      = jsonencode(
            {
              + Statement = [
                  + {
                      + Effect    = "Allow"
                      + NotAction = [
                          + "iam:*",
                          + "organizations:*",
                          + "account:*",
                        ]
                      + Resource  = "*"
                      + Sid       = ""
                    },
                  + {
                      + Action   = [
                          + "iam:CreateServiceLinkedRole",
                          + "iam:DeleteServiceLinkedRole",
                          + "iam:ListRoles",
                          + "organizations:DescribeOrganization",
                          + "account:ListRegions",
                        ]
                      + Effect   = "Allow"
                      + Resource = "*"
                      + Sid      = ""
                    },
                  + {
                      + Action   = "iam:passrole"
                      + Effect   = "Allow"
                      + Resource = "arn:aws:iam::353532242242:role/ec2_basic"
                      + Sid      = "passec2basic"
                    },
                  + {
                      + Action    = [
                          + "ssm:*",
                          + "cloudformation:*",
                        ]
                      + Condition = {
                          + stringequals = {
                              + "aws:resourcetag/environment" = "prod"
                            }
                        }
                      + Effect    = "Allow"
                      + Resource  = "*"
                      + Sid       = "environmentaccess"
                    },
                ]
              + Version   = "2012-10-17"
            }
        )

Which works out to

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "NotAction": [
        "iam:*",
        "organizations:*",
        "account:*"
      ],
      "Resource": "*"
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Action": [
        "iam:CreateServiceLinkedRole",
        "iam:DeleteServiceLinkedRole",
        "iam:ListRoles",
        "organizations:DescribeOrganization",
        "account:ListRegions"
      ],
      "Resource": "*"
    },
    {
      "Sid": "passEc2Basic",
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::496396001060:role/ec2_basic"
    },
    {
      "Sid": "environmentAccess",
      "Effect": "Allow",
      "Action": [
        "ssm:*",
        "cloudformation:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/Environment": "prod"
        }
      }
    }
  ]
}

I have checked this in the console and it works.

So, where is this error coming from?

: error creating IAM Policy foo_user_prod: MalformedPolicyDocument: Syntax errors in policy.


Solution

  • The Problem comes from the condition in the data.aws_iam_policy_document.poweruser_extended_prod definition.

    Terraform uses a slightly off syntax for its condition. Changing the test value from stringequals to ForAnyValue:StringEquals solved the problem of the syntax error.