question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

(custom-resources): AwsCustomResource ignores the configured role if a prior instance was already instantiated

See original GitHub issue

This issue was repurposed following https://github.com/aws/aws-cdk/issues/13601#issuecomment-803574616.

Original report


When you enable logging in software.amazon.awscdk.services.elasticsearch, and you are creating log groups, then internally it instantiate the LogGroupResourcePolicy which extends the AWSCustomResource This in turn, sets the AWSCustomResource, which may overwrite any other AWSCustomResource role deployed in the same stack, or have its role overwritten. The reason it overwrites the role, is that the AWSCustomResource role is a singleton for the entire stack

This role will apply to all AwsCustomResource instances in the stack https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_custom-resources.AwsCustomResource.html#role

Reproduction Steps

Python code, Irrelevant code removed for brevity. The main point is to turn on logging with log groups and basically get LogGroupResourcePolicy be to instantiated

# Create my custom resource with a singleton role which I use in the entire stack for all other custom resoruces
policy = AwsCustomResourcePolicy.from_sdk_calls(resources=[f'arn:aws:iot:{region}:{account_id}:rolealias/{role_alias}'])
# This is a singleton class that returns the one role used in my stack
lambda_role_singleton = CustomResourcesLambdaRole(scope)
lambda_role_singleton.add_to_policy(actions=["iam:PassRole"], resources=[role_arn])

AwsCustomResource(scope=self, id='CustomResource', policy=policy, log_retention=log_retention,
                                                on_create=on_create, on_update=on_update, on_delete=on_delete,
                                                resource_type='Custom::AWS-IoT-Role-Alias', role=lambda_role_singleton.role,
                                                timeout=timeout)

# Create the ES domain with logging turned on and log groups
aws_cdk.aws_elasticsearch.Domain(
            scope=self,
            id=id,
            version=ElasticsearchVersion.V7_9,
            logging=self._create_logging_options()
           ....)

def _create_logging_options(self) -> LoggingOptions:
        return LoggingOptions(app_log_enabled=True, slow_index_log_enabled=True, slow_search_log_enabled=True,
                              app_log_group=self._create_log_group(log_group_type=LogGroupType.APP),
                              slow_index_log_group=self._create_log_group(log_group_type=LogGroupType.SLOW_INDEX),
                              slow_search_log_group=self._create_log_group(log_group_type=LogGroupType.SLOW_SEARCH))
 
def _create_log_group(self, log_group_type: str) -> LogGroup:
        return LogGroup(scope=self, id=log_group_type.value.capitalize(), log_group_name=<log-group-name>,
                        removal_policy=RemovalPolicy.DESTROY)

What did you expect to happen?

Both my custom resource and ES domain are deployed

What actually happened?

Deployment failed since I was missing the “iam:PassRole” permissions required to deploy a role alias. Inspecting the cdk.out template, I saw that indeed, this wasn’t present on the role policy. and this was only missing when the ES domain was deployed with logging turned on.

Environment

  • CDK CLI Version : 1.91
  • Framework Version: 1.91
  • Node.js Version: v12.16.0
  • OS : MacOS, Linux
  • Language (Version): Python 3.8

Other

Unless i’m missing something, a possible solution would allow me to pass the role that will be used or something similar with the logging options.


This is 🐛 Bug Report

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:10 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
iliapolocommented, Mar 21, 2021

@royby-cyberark Thanks for being so detailed!

Yes you’re right, I neglected to consider the order of creation. Basically what happens is that the role of the custom resource is created when the domain is instantiated.

After this, any role passed to AwsCustomResource is effectively ignored since it reuses the already existing lambda function (which has a different role).

To workaround this, apart from re-arranging the order of instantiation, you can also avoid creating a dedicated role, and simply add policies to the existing one.

my_custom_resource = cr.AwsCustomResource(
            scope=self, id='MyAwsCustomResource', 
            # role=role, # dont pass a role
            policy=cr.AwsCustomResourcePolicy.from_sdk_calls(resources=['*']),
            on_create=cr.AwsSdkCall(
                action='listBuckets',
                service='s3',
                physical_resource_id=cr.PhysicalResourceId.of('BucketsList'),)
        )

my_custom_resource.grant_principal.add_to_policy(...)

I do agree this is confusing though. But it’s more related to how AwsCustomResource behaves, rather than its usage by the elasticsearch domain, which is actually as intended.

Im going to route this to the custom-resources package for further discussion.

FYI @rix0rrr do you think there is something we can do here? Intuitively I would expect that any property that can be passed by the user, should be encoded in the UUID of the function, otherwise they are all similarly ignored.

1reaction
royby-cyberarkcommented, Oct 3, 2021

@txsutton I wasn’t able to make progress with it. it worked for me so far by allowing ‘*’ which was fine for this use case, so I didn’t get to invest in this further.

Read more comments on GitHub >

github_iconTop Results From Across the Web

aws-cdk/custom-resources module - AWS Documentation
AWS CloudFormation custom resources are extension points to the provisioning engine. When CloudFormation needs to create, update or delete a custom resource ...
Read more >
Advanced Custom Resources with AWS CDK - Medium
In Part 1, we learned what AWS CloudFormation custom resources are and how to create a custom resource using the AWS CDK's AWSCustomResource...
Read more >
@aws-cdk/custom-resources | Yarn - Package Manager
When CloudFormation needs to create, update or delete a custom resource, it sends a lifecycle event notification to a custom resource provider. The...
Read more >
AWS CDK v2 Tutorial – How to Create a Three-Tier Serverless ...
In this tutorial, we will create a simple note-taking application using a DynamoDB table, HTTP API endpoints, Lambda handlers, and a frontend ...
Read more >
pablissimo.com – Paul O'Neill, Edinburgh-based software ...
For example, I had 'example.com' set up as a verified identity in SES allowing ... these will represent the IAM role of the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found