amazon-web-servicesaws-service-catalogaws-cdk

CDK - How to get object reference to resource that is added to CFN template in the background by method


Once I mitigate ResourceNotFoundException when trying to add ServiceCatalog LaunchRoleConstraint to the Portfolio.

It turned out, that in the background, CDK is creating PortfolioProductAssociation when portfolio_obj.add_product(product_obj) method is used.

It work fine until you want to add an existing role - then you need to use CfnLaunchRoleConstraint instead of using e.g. portfolio_obj.set_local_launch_role_name(). set_local_launch_role_name() method by default adds proper depends on to association object - pure CfnLaunchRoleConstraint object is not.

So, here we can mitigate ResourceNotFoundException because setting-up launch constraints requires already done association of the product to the portfolio - appropriate depends on reference is required.

To fix it I just use CfnPortfolioProductAssociation instead add_product method, so I was able to create depends on with association...


My question is: is it possible to somehow retrieve such objects, like this association object (generated by add_product() method), into my stack class, to be able to refer to them?

I know that is not a necessary functionality, due to each Cfn* resource - I'm just curious...

(I'm using Python CDK-v2)


Solution

  • Yes, you can retrieve the underlying Cfn* objects that are created by L2 objects, either in the constructor, or through helper functions like add_product() by using escape hatches:

    https://docs.aws.amazon.com/cdk/v2/guide/cfn_layer.html#cfn_layer_resource

    The trick about this is getting the Id of the resource you want. Sometimes you can just use node.default_child but if it's not the default child of the L2/L3 construct then you may need node.find_child. But that can be tough because in this case the Id is not a static value and would be hard to guess:

    https://github.com/aws/aws-cdk/blob/74318c7d22bfc00de9e005f68a0a6aaa58c7db39/packages/%40aws-cdk/aws-servicecatalog/lib/private/association-manager.ts#L24

    So instead you can look at just iterating over all children until you find the CfnPortfolioProductAssociation class. I'm not a python guy so I'm going to psuedo code it here:

    for resource in thing.node.children:
        if isinstance(resource, CfnPortfolioProductAssociation):
            # start modifying resource here as needed
    
    

    Note: if I got the python code here wrong PLEASE edit this response to fix it.