aws-cdk: Immutable roles cannot be used as constructs

Hi!

After upgrading to CDK 1.29.0 we are seeing the following error:

Error: construct does not have an associated node
    at Function.of (/node_modules/constructs/lib/construct.ts:31:13)
    at new Node (/node_modules/constructs/lib/construct.ts:74:12)
    at new ConstructNode (/node_modules/@aws-cdk/core/lib/construct-compat.ts:260:24)
    at Object.createNode (/node_modules/@aws-cdk/core/lib/construct-compat.ts:69:11)
    at new Construct (/node_modules/constructs/lib/construct.ts:541:26)
    at new Construct (/node_modules/@aws-cdk/core/lib/construct-compat.ts:66:5)
    at new SingletonPolicy (/node_modules/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts:517:5)
    at Function.forRole (/node_modules/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts:507:42)
    at CloudFormationCreateUpdateStackAction.bound (/node_modules/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts:300:21)
    at CloudFormationCreateUpdateStackAction.bound (/node_modules/@aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts:436:32)

Reproduction Steps

A full repro here https://github.com/markusl/temp-aws-issue-repro

Environment

  • CLI Version : 0.30.0
  • Framework Version: 0.30.0
  • OS : Macbook
  • Language : TypeScript

This is 🐛 Bug Report

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 37 (32 by maintainers)

Commits related to this issue

Most upvoted comments

Got it. This is indeed a bug!

The IAM role you are importing is from a different account. Therefore, Role.fromArn returns an IRole that is backed by an ImmutableRole object (because there is no way for you to mutate a role in a different account). So far so good.

The culprit is that SingletonPolicy inside codepipeline-actions assumes the IRole passed to it is a Construct by performing an explicit downcast (role as unknown as cdk.Construct). This worked in the past because ImmutableRole exposes node property which allowed it to implement IConstruct.

https://github.com/aws/aws-cdk/blob/4501b8ba566ac776042fc97435d4db96fc421e0b/packages/%40aws-cdk/aws-codepipeline-actions/lib/cloudformation/pipeline-actions.ts#L517

In 1.29.0, due to some constraints when we extracted constructs into an outside library, we had to change the way nodes are associated with constructs and therefore it is now impossible to downcast objects that implement IConstruct to Construct.