From a26f7ee0f09dac386451b7e195a72d359bb58101 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Mon, 10 Jun 2019 12:14:02 +0200 Subject: [PATCH] fix(iam): support adding permissions to imported roles Now create a Policy and attach it to imported roles as well. This will only work for imported roles in the same account. If you need to reference roles in other accounts without trying to add these policy statements, use an `AwsPrincipal`. Relates to #2381, #2651, #2652, #2662. --- packages/@aws-cdk/aws-iam/lib/role.ts | 18 ++++++++++---- packages/@aws-cdk/aws-iam/test/test.role.ts | 27 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-iam/lib/role.ts b/packages/@aws-cdk/aws-iam/lib/role.ts index 56bcd5de1d2bc..2018845f75db8 100644 --- a/packages/@aws-cdk/aws-iam/lib/role.ts +++ b/packages/@aws-cdk/aws-iam/lib/role.ts @@ -116,13 +116,21 @@ export class Role extends Resource implements IRole { public readonly roleArn = roleArn; public readonly roleName = Stack.of(scope).parseArn(roleArn).resourceName!; - public addToPolicy(_statement: PolicyStatement): boolean { - // Statement will be added to resource instead - return false; + private readonly attachedPolicies = new AttachedPolicies(); + private defaultPolicy?: Policy; + + public addToPolicy(statement: PolicyStatement): boolean { + if (!this.defaultPolicy) { + this.defaultPolicy = new Policy(this, 'Policy'); + this.attachInlinePolicy(this.defaultPolicy); + } + this.defaultPolicy.addStatement(statement); + return true; } - public attachInlinePolicy(_policy: Policy): void { - // FIXME: Add warning that we're ignoring this + public attachInlinePolicy(policy: Policy): void { + this.attachedPolicies.attach(policy); + policy.attachToRole(this); } public attachManagedPolicy(_arn: string): void { diff --git a/packages/@aws-cdk/aws-iam/test/test.role.ts b/packages/@aws-cdk/aws-iam/test/test.role.ts index c3783e814ba4d..8c8ad2a00d290 100644 --- a/packages/@aws-cdk/aws-iam/test/test.role.ts +++ b/packages/@aws-cdk/aws-iam/test/test.role.ts @@ -260,5 +260,32 @@ export = { test.deepEqual(importedRole.roleArn, 'arn:aws:iam::123456789012:role/S3Access'); test.deepEqual(importedRole.roleName, 'S3Access'); test.done(); + }, + + 'add policy to imported role'(test: Test) { + // GIVEN + const stack = new Stack(); + const importedRole = Role.fromRoleArn(stack, 'ImportedRole', 'arn:aws:iam::123456789012:role/MyRole'); + + // WHEN + importedRole.addToPolicy(new PolicyStatement() + .addAction('s3:*') + .addResource('xyz')); + + // THEN + expect(stack).to(haveResource('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: "s3:*", + Effect: "Allow", + Resource: "xyz" + } + ], + Version: "2012-10-17" + }, + Roles: [ "MyRole" ] + })); + test.done(); } };