Skip to content

Commit 7c9cb6d

Browse files
author
Elad Ben-Israel
committed
fix(dam): immutable role cannot be used as a construct
Due to a change in how `ConstructNode`s are associated with `Construct`s in 1.29.0, `ImmutableRole`'s "impersonation to a construct" -- by reflecting the construct's `node` property -- no longer works. This change simply turns `ImmutableRole` into a real construct by extending the `Construct` base class. This fixes the use case in #6885
1 parent f50b876 commit 7c9cb6d

3 files changed

Lines changed: 14 additions & 7 deletions

File tree

packages/@aws-cdk/aws-iam/lib/private/immutable-role.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DependableTrait } from '@aws-cdk/core';
1+
import { Construct, DependableTrait } from '@aws-cdk/core';
22
import { Grant } from '../grant';
33
import { IManagedPolicy } from '../managed-policy';
44
import { Policy } from '../policy';
@@ -19,16 +19,17 @@ import { IRole } from '../role';
1919
* which was imported into the CDK with {@link Role.fromRoleArn}, you don't have to use this class -
2020
* simply pass the property mutable = false when calling {@link Role.fromRoleArn}.
2121
*/
22-
export class ImmutableRole implements IRole {
22+
export class ImmutableRole extends Construct implements IRole {
2323
public readonly assumeRoleAction = this.role.assumeRoleAction;
2424
public readonly policyFragment = this.role.policyFragment;
2525
public readonly grantPrincipal = this;
2626
public readonly roleArn = this.role.roleArn;
2727
public readonly roleName = this.role.roleName;
28-
public readonly node = this.role.node;
2928
public readonly stack = this.role.stack;
3029

31-
constructor(private readonly role: IRole) {
30+
constructor(scope: Construct, id: string, private readonly role: IRole) {
31+
super(scope, id);
32+
3233
// implement IDependable privately
3334
DependableTrait.implement(this, {
3435
dependencyRoots: [ role ]

packages/@aws-cdk/aws-iam/lib/role.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ export class Role extends Resource implements IRole {
235235

236236
return options.mutable !== false && accountsAreEqualOrOneIsUnresolved(scopeAccount, roleAccount)
237237
? new Import(scope, id)
238-
: new ImmutableRole(new Import(scope, id));
238+
: new ImmutableRole(scope, `ImmutableRole${id}`, new Import(scope, id));
239239

240240
function accountsAreEqualOrOneIsUnresolved(account1: string | undefined,
241241
account2: string | undefined): boolean {
@@ -401,7 +401,7 @@ export class Role extends Resource implements IRole {
401401
* Role's policies yourself.
402402
*/
403403
public withoutPolicyUpdates(): IRole {
404-
return new ImmutableRole(this);
404+
return new ImmutableRole(this.node.scope as Construct, `ImmutableRole${this.node.id}`, this);
405405
}
406406
}
407407

packages/@aws-cdk/aws-iam/test/immutable-role.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import '@aws-cdk/assert/jest';
2-
import { Stack } from '@aws-cdk/core';
2+
import { Construct, Stack } from '@aws-cdk/core';
33
import * as iam from '../lib';
44

55
// tslint:disable:object-literal-key-quotes
@@ -106,4 +106,10 @@ describe('ImmutableRole', () => {
106106
},
107107
});
108108
});
109+
110+
// this pattern is used here:
111+
// aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts#L517
112+
test('immutable role is a construct', () => {
113+
new Construct(immutableRole as unknown as Construct, 'Child');
114+
});
109115
});

0 commit comments

Comments
 (0)