IAM policy with both an array Statement and single Statement

Hi all,

I’m currently writing a Sentinel policy that needs to check if an IAM policy has the following conditions set: s.Action is "*" and s.Effect is "Allow" and s.Resource is "*". I found the following code on GitHub which allowed me to do this:

This works with the following Terraform resource:

resource "aws_iam_policy" "policy" {
  name        = "example_policy"
  path        = "/"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "ec2:CreateSecurityGroup"
        Effect   = "Allow"
        Resource = "*"
      },
      {
        Action = "*"
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}

and successfully passes my tests. However, if I do the following:

resource "aws_iam_policy" "policy" {
  name        = "example_policy"
  path        = "/"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = {
        Action = "ec2:CreateSecurityGroup"
        Effect   = "Allow"
        Resource = "*"
    }
  })
}

This gives me the following error:

math: non-number operation on different types (list/map)

I’m unsure of how to modify the code on GitHub to account for both array statements and single statements (like the two examples above). I couldn’t find anything in the documentation about checking for types in scenarios like this?

Also, how would I go about switching this over to work with tfplan/v2? I noticed that the mocks for tfplan/v2 doesn’t contain the module_paths parameter.

@andredms here is a refactored example that uses the tfplan/v2 import.

I have added comments that include documentation references that should help you understand what I have done.

TL;DR Use the types import to determine the type of value that you are working with and then use the case statement to handle the values accordingly. You could also use an if statement but I prefer to use case.

Here is another IAM example that uses the tfplan/v2 import as well as tfplan-functions helper module.