From 7ad8bc0b23b17567c545960e7c890cc100dd2bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fynn=20Fl=C3=BCgge?= Date: Wed, 1 Mar 2023 02:00:51 +0100 Subject: [PATCH] chore(iam): throw warning if managed policies attached to a group exceeds 10 (#24385) Throw a warning if more than 10 managed policies are attached to an IAM group. Added [IAM and AWS STS quotas, name requirements, and character limits](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html#reference_iam-quotas-entities) to documentation indicating current quotas. Closes #24085. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-iam/lib/group.ts | 15 ++++++- packages/@aws-cdk/aws-iam/test/group.test.ts | 43 +++++++++++++++++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-iam/lib/group.ts b/packages/@aws-cdk/aws-iam/lib/group.ts index 0b81c6c572158..850c9a4a660d1 100644 --- a/packages/@aws-cdk/aws-iam/lib/group.ts +++ b/packages/@aws-cdk/aws-iam/lib/group.ts @@ -1,4 +1,4 @@ -import { ArnFormat, Lazy, Resource, Stack } from '@aws-cdk/core'; +import { Annotations, ArnFormat, Lazy, Resource, Stack } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { CfnGroup } from './iam.generated'; import { IIdentity } from './identity-base'; @@ -200,14 +200,25 @@ export class Group extends GroupBase { // Removes leading slash from path resourceName: `${props.path ? props.path.substr(props.path.charAt(0) === '/' ? 1 : 0) : ''}${this.physicalName}`, }); + + this.managedPoliciesExceededWarning(); } /** - * Attaches a managed policy to this group. + * Attaches a managed policy to this group. See [IAM and AWS STS quotas, name requirements, and character limits] + * (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html#reference_iam-quotas-entities) + * for quota of managed policies attached to an IAM group. * @param policy The managed policy to attach. */ public addManagedPolicy(policy: IManagedPolicy) { if (this.managedPolicies.find(mp => mp === policy)) { return; } this.managedPolicies.push(policy); + this.managedPoliciesExceededWarning(); + } + + private managedPoliciesExceededWarning() { + if (this.managedPolicies.length > 10) { + Annotations.of(this).addWarning(`You added ${this.managedPolicies.length} to IAM Group ${this.physicalName}. The maximum number of managed policies attached to an IAM group is 10.`); + } } } diff --git a/packages/@aws-cdk/aws-iam/test/group.test.ts b/packages/@aws-cdk/aws-iam/test/group.test.ts index 6d0a4e83e05cc..7ea6580d51ea9 100644 --- a/packages/@aws-cdk/aws-iam/test/group.test.ts +++ b/packages/@aws-cdk/aws-iam/test/group.test.ts @@ -1,4 +1,4 @@ -import { Template } from '@aws-cdk/assertions'; +import { Annotations, Template } from '@aws-cdk/assertions'; import { App, CfnResource, Stack } from '@aws-cdk/core'; import { Group, ManagedPolicy, User } from '../lib'; @@ -103,3 +103,44 @@ test('cross-env group ARNs include path', () => { }, }); }); + +test('throw warning if attached managed policies exceed 10 in constructor', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new Group(stack, 'MyGroup', { + groupName: 'MyGroup', + managedPolicies: [ + ManagedPolicy.fromAwsManagedPolicyName('0'), + ManagedPolicy.fromAwsManagedPolicyName('1'), + ManagedPolicy.fromAwsManagedPolicyName('2'), + ManagedPolicy.fromAwsManagedPolicyName('3'), + ManagedPolicy.fromAwsManagedPolicyName('4'), + ManagedPolicy.fromAwsManagedPolicyName('5'), + ManagedPolicy.fromAwsManagedPolicyName('6'), + ManagedPolicy.fromAwsManagedPolicyName('7'), + ManagedPolicy.fromAwsManagedPolicyName('8'), + ManagedPolicy.fromAwsManagedPolicyName('9'), + ManagedPolicy.fromAwsManagedPolicyName('10'), + ], + }); + + Annotations.fromStack(stack).hasWarning('*', 'You added 11 to IAM Group MyGroup. The maximum number of managed policies attached to an IAM group is 10.'); +}); + +test('throw warning if attached managed policies exceed 10 when calling `addManagedPolicy`', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + const group = new Group(stack, 'MyGroup', { + groupName: 'MyGroup', + }); + + for (let i = 0; i <= 11; i++) { + group.addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName(i.toString())); + } + + Annotations.fromStack(stack).hasWarning('/Default/MyGroup', 'You added 11 to IAM Group MyGroup. The maximum number of managed policies attached to an IAM group is 10.'); +});