diff --git a/CHANGELOG.md b/CHANGELOG.md index 05aa748df..1ec3b8ef0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -107,6 +107,7 @@ BUG FIXES: * provider/aws: aws_ami: handle deletion of AMIs [GH-9721] * provider/aws: Fix aws_route53_record alias perpetual diff [GH-9704] * provider/aws: Allow `active` state while waiting for the VPC Peering Connection. #9754 + * provider/aws: Normalize all-principals wildcard in `aws_iam_policy_document` [GH-9720] * provider/azurerm: Fix Azure RM loadbalancer rules validation [GH-9468] * provider/azurerm: Fix servicebus_topic values when using the Update func to stop perpetual diff [GH-9323] * provider/azurerm: lower servicebus_topic max size to Azure limit [GH-9649] diff --git a/builtin/providers/aws/data_source_aws_iam_policy_document_test.go b/builtin/providers/aws/data_source_aws_iam_policy_document_test.go index a50a8ae29..a720d181a 100644 --- a/builtin/providers/aws/data_source_aws_iam_policy_document_test.go +++ b/builtin/providers/aws/data_source_aws_iam_policy_document_test.go @@ -106,6 +106,24 @@ data "aws_iam_policy_document" "test" { not_resources = ["arn:aws:s3:::*"] } + # Normalization of wildcard principals + statement { + effect = "Allow" + actions = ["kinesis:*"] + principals { + type = "AWS" + identifiers = ["*"] + } + } + statement { + effect = "Allow" + actions = ["firehose:*"] + principals { + type = "*" + identifiers = ["*"] + } + } + } ` @@ -156,6 +174,18 @@ var testAccAWSIAMPolicyDocumentExpectedJSON = `{ "Effect": "Deny", "NotAction": "s3:*", "NotResource": "arn:aws:s3:::*" + }, + { + "Sid": "", + "Effect": "Allow", + "Action": "kinesis:*", + "Principal": "*" + }, + { + "Sid": "", + "Effect": "Allow", + "Action": "firehose:*", + "Principal": "*" } ] }` diff --git a/builtin/providers/aws/iam_policy_model.go b/builtin/providers/aws/iam_policy_model.go index 59192fbf1..81306971d 100644 --- a/builtin/providers/aws/iam_policy_model.go +++ b/builtin/providers/aws/iam_policy_model.go @@ -40,6 +40,23 @@ type IAMPolicyStatementConditionSet []IAMPolicyStatementCondition func (ps IAMPolicyStatementPrincipalSet) MarshalJSON() ([]byte, error) { raw := map[string]interface{}{} + // As a special case, IAM considers the string value "*" to be + // equivalent to "AWS": "*", and normalizes policies as such. + // We'll follow their lead and do the same normalization here. + // IAM also considers {"*": "*"} to be equivalent to this. + if len(ps) == 1 { + p := ps[0] + if p.Type == "AWS" || p.Type == "*" { + if sv, ok := p.Identifiers.(string); ok && sv == "*" { + return []byte(`"*"`), nil + } + + if av, ok := p.Identifiers.([]string); ok && len(av) == 1 && av[0] == "*" { + return []byte(`"*"`), nil + } + } + } + for _, p := range ps { switch i := p.Identifiers.(type) { case []string: