aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.55k stars 3.87k forks source link

aws_iam: CfnPolicy optional properties are in practice required #31424

Closed williwlwilliwll closed 2 weeks ago

williwlwilliwll commented 2 weeks ago

Describe the bug

CfnPolicyProps defines the roles, users, and groups properties as optional however you run into an error during deployment if you do not assign a value to one of them.

Regression Issue

Last Known Working CDK Version

No response

Expected Behavior

You should be able to create a CfnPolicy construct without assigning a value to its users, roles and groups properties. As per the CfnPolicyProps in the source code:

    /**
     * The name of the group to associate the policy with.
     *
     * This parameter allows (through its [regex pattern](https://docs.aws.amazon.com/http://wikipedia.org/wiki/regex) ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: _+=,.@-.
     *
     * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html#cfn-iam-policy-groups
     */
    readonly groups?: Array<string>;

    [ .... ]

    /**
     * The name of the role to associate the policy with.
     *
     * This parameter allows (per its [regex pattern](https://docs.aws.amazon.com/http://wikipedia.org/wiki/regex) ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: _+=,.@-
     *
     * > If an external policy (such as `AWS::IAM::Policy` or `AWS::IAM::ManagedPolicy` ) has a `Ref` to a role and if a resource (such as `AWS::ECS::Service` ) also has a `Ref` to the same role, add a `DependsOn` attribute to the resource to make the resource depend on the external policy. This dependency ensures that the role's policy is available throughout the resource's lifecycle. For example, when you delete a stack with an `AWS::ECS::Service` resource, the `DependsOn` attribute ensures that AWS CloudFormation deletes the `AWS::ECS::Service` resource before deleting its role's policy.
     *
     * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html#cfn-iam-policy-roles
     */
    readonly roles?: Array<string>;
    /**
     * The name of the user to associate the policy with.
     *
     * This parameter allows (through its [regex pattern](https://docs.aws.amazon.com/http://wikipedia.org/wiki/regex) ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: _+=,.@-
     *
     * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html#cfn-iam-policy-users
     */
    readonly users?: Array<string>;
}

Current Behavior

When you create a CfnPolicy without assigning a value to the users, groups and roles properties then during deployment the following error is thrown:

11:00:05 AM | CREATE_FAILED        | AWS::IAM::Policy   | iamEcrReadOnly
Resource handler returned message: "At least one of [Groups,Roles,Users] must be non-empty." (RequestToken:
c4734d73-c872-80ff-7911-ABC1234, HandlerErrorCode: InvalidRequest)

Reproduction Steps

        const ecrReadOnly = new iam.CfnPolicy(this, 'iam-EcrReadOnly', {
            policyDocument: {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Action": [
                            "ecr:BatchCheckLayerAvailability",
                            "ecr:BatchGetImage",
                            "ecr:GetDownloadUrlForLayer",
                            "ecr:GetAuthorizationToken"
                        ],
                        "Resource": "*"
                    }
                ]
            },
            policyName: 'iam-EcrReadOnly'
        })

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.158.0

Framework Version

2.158.0

Node.js Version

22.8.0

OS

MacOS Sonoma 14.6.1

Language

TypeScript

Language Version

No response

Other information

No response

ashishdhingra commented 2 weeks ago

@williwlwilliwll Good morning. Thanks for opening the issue.

AWS::IAM::Policy specifies that it Adds or updates an inline policy document that is embedded in the specified IAM group, user or role.. So it's an inline policy document that must be embedded in either one of group, user or role. Hence the error.

CfnPolicy is an L1 construct that is generated from CloudFormation resource specification (refer AWS::IAM::Policy and CloudFormationResourceSpecification.json). The CloudFormation resource specification specifies Groups, Roles and Users as optional. All of these properties are not required, however, to embed the inline policy, at least one of them is required.

You may try using CfnManagedPolicy L1 construct which represents AWS::IAM::ManagedPolicy resource in case you want to create standalone policy.

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as iam from 'aws-cdk-lib/aws-iam';

export class CdkinittestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new iam.CfnManagedPolicy(this, 'iam-EcrReadOnly', {
      policyDocument: {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "ecr:BatchCheckLayerAvailability",
              "ecr:BatchGetImage",
              "ecr:GetDownloadUrlForLayer",
              "ecr:GetAuthorizationToken"
            ],
            "Resource": "*"
          }
        ]
      },
      managedPolicyName: 'iam-EcrReadOnly'
    });
  }
}

Thanks, Ashish

williwlwilliwll commented 2 weeks ago

Hi @ashishdhingra,

Thank you for taking the time to explain that :). I didn't read the docs well enough, I'm sorry to have wasted your time!

Best,

Will

github-actions[bot] commented 2 weeks ago

Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.