aws-cdk: aws-cdk-lib/aws-servicecatalog: Using locally deployed launch role in end user account not working

Describe the bug

The documentation states:

You can also set the launch role using just the name of a role which is locally deployed in end user accounts. 
This is useful for when roles and users are separately managed outside of the CDK. 
The given role must exist in both the account that creates the launch role constraint, 
as well as in any end user accounts that wish to provision a product with the launch role.

You can do this by passing in the role with an explicitly set name:
import * as iam from 'aws-cdk-lib/aws-iam';

declare const portfolio: servicecatalog.Portfolio;
declare const product: servicecatalog.CloudFormationProduct;

const launchRole = new iam.Role(this, 'LaunchRole', {
  roleName: 'MyRole',
  assumedBy: new iam.ServicePrincipal('servicecatalog.amazonaws.com'),
});

portfolio.setLocalLaunchRole(product, launchRole);
Or you can simply pass in a role name and CDK will create a role
with that name that trusts service catalog in the account:
import * as iam from 'aws-cdk-lib/aws-iam';

declare const portfolio: servicecatalog.Portfolio;
declare const product: servicecatalog.CloudFormationProduct;

const roleName = 'MyRole';
const launchRole: iam.IRole = portfolio.setLocalLaunchRoleName(product, roleName);

I’ve used both approaches trying to set the launch role, but getting the unexpected result:

MY_FANCY_ROLE_NAME already exists in stack 
arn:aws:cloudformation:region-1:account:stack/SomeOtherStackWhereMY_FANCY_ROLE_EXISTS_AS_EXPECTED

The doc is saying that I need to have the same role on both accounts already existing, which is the case, but CDK tries to create a new role in the portfolio account with the name what already exists.

Expected Behavior

I expect that:

  • I’ provide the name (MY_FANCY_ROLE) which exists in portfolio account and also in other AWS Account with which I’m sharing my portfolio and this is going to work.
  • In the target account I don’t have to add the permissions to launch manually to launch the product
  • There is no new role (as a AWS resource) created in the portfolio account

Current Behavior

Actually CloudFormation can’t create the LaunchRole with name MY_FANCY_NAME what obviously already exists in the portfolio account what leads to rejecting of the portfolio resource update.

Reproduction Steps

  • same aws roles in both aws accounts needed (portfoli+target account)
  • change the target id in the code below for target account
  • deploy the code in the portfolio account
  • uncomment the role section and adjust the role name (MY_FANCY_ROLE)
  • try again to deploy the code
import { Stack, StackProps } from 'aws-cdk-lib'
import { Construct } from 'constructs'
import {
  CloudFormationProduct,
  CloudFormationTemplate,
  MessageLanguage,
  Portfolio,
} from 'aws-cdk-lib/aws-servicecatalog'
import { ExampleApplicationProductStack } from './example-application-product-stack'
import { IRole, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam'

export class PortfolioStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    const portfolio = new Portfolio(this, 'test-portfolio', {
      displayName: 'SomeDisplayName',
      description: 'SomeDesc',
      providerName: 'SomeProviderName',
      messageLanguage: MessageLanguage.EN,
    })
    portfolio.shareWithAccount('TARGET_ACCOUNT_ID')
    const product = new CloudFormationProduct(this, 'Product', {
      productName: 'SampleProduct',
      owner: 'OWNER',
      productVersions: [
        {
          productVersionName: 'v1',
          cloudFormationTemplate: CloudFormationTemplate.fromProductStack(
            new ExampleApplicationProductStack(this, 'product-application-product-stack'),
          ),
        },
      ],
    })

    portfolio.addProduct(product)

    // const launchRole: IRole = new Role(this, 'LaunchRole', {
    //   roleName: 'MY_FANCY_ROLE',
    //   assumedBy: new ServicePrincipal('servicecatalog.amazonaws.com'),
    // })
    //
    // portfolio.setLocalLaunchRole(product, launchRole)
  }
}

Possible Solution

There should be not created a new role as a resource, hence reused the existing one.

Additional Information/Context

No response

CDK CLI Version

2.23.0 (build 50444aa)

Framework Version

No response

Node.js Version

v16.15.0

OS

Windows

Language

Typescript

Language Version

TypeScript (4.6.4)

Other information

No response

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 18 (12 by maintainers)

Most upvoted comments

Thanks, will look. I think we might know what’s going on.