diff --git a/packages/aws-cdk-lib/aws-iam/lib/role.ts b/packages/aws-cdk-lib/aws-iam/lib/role.ts index 0e7d451341eda..b2e38505cc967 100644 --- a/packages/aws-cdk-lib/aws-iam/lib/role.ts +++ b/packages/aws-cdk-lib/aws-iam/lib/role.ts @@ -549,7 +549,7 @@ export class Role extends Resource implements IRole { if (this._precreatedRole) { return this._precreatedRole.addManagedPolicy(policy); } else { - if (this.managedPolicies.find(mp => mp === policy)) { return; } + if (this.managedPolicies.some(mp => mp.managedPolicyArn === policy.managedPolicyArn)) { return; } this.managedPolicies.push(policy); } } diff --git a/packages/aws-cdk-lib/aws-iam/test/role.test.ts b/packages/aws-cdk-lib/aws-iam/test/role.test.ts index 82791ec8e0af3..5d239254d5bbc 100644 --- a/packages/aws-cdk-lib/aws-iam/test/role.test.ts +++ b/packages/aws-cdk-lib/aws-iam/test/role.test.ts @@ -1166,7 +1166,18 @@ test('managed policy ARNs are deduplicated', () => { ManagedPolicy.fromAwsManagedPolicyName('SuperDeveloper'), ], }); - role.addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName('SuperDeveloper')); + role.addToPrincipalPolicy( + new PolicyStatement({ + actions: ['s3:*'], + resources: ['*'], + }), + ); + + for (let i = 0; i < 20; i++) { + role.addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName('SuperDeveloper')); + } + + Annotations.fromStack(stack).hasNoWarning('/my-stack/MyRole', Match.stringLikeRegexp('.*')); Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { ManagedPolicyArns: [ @@ -1184,6 +1195,26 @@ test('managed policy ARNs are deduplicated', () => { }); }); +test('too many managed policies warning', () => { + const app = new App(); + const stack = new Stack(app, 'my-stack'); + const role = new Role(stack, 'MyRole', { + assumedBy: new ServicePrincipal('sns.amazonaws.com'), + }); + role.addToPrincipalPolicy( + new PolicyStatement({ + actions: ['s3:*'], + resources: ['*'], + }), + ); + + for (let i = 0; i < 20; i++) { + role.addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName(`SuperDeveloper${i}`)); + } + + Annotations.fromStack(stack).hasWarning('/my-stack/MyRole', Match.stringLikeRegexp('.*')); +}); + describe('role with too large inline policy', () => { const N = 100;