AWS CDK Lambda function_from_arn not working as expected

467 views Asked by At

I have this Lambda and this DynamoDB table

my_lambda = lambda_.Function(
    self,
    "my_lambda",
    function_name="my_lambda",
    description="A Lambda to test permissions",
    code=lambda_code,
    memory_size=512,
    handler="my_lambda.main",
    runtime=lambda_.Runtime.PYTHON_3_9,
    architecture=lambda_.Architecture.ARM_64,
    timeout=Duration.minutes(1),
)


table = dynamodb.Table(
    self,
    'test_table',
    partition_key=dynamodb.Attribute(
        name="id",
        type=dynamodb.AttributeType.STRING,
    ),
)

Now, if I want to give the Lambda access to write in the DynameDB table I do this.

table.grant_full_access(my_lambda)

This works perfectly. Now, if I want to give this same Lambda access to the table be getting a reference to it it doesn't work.

lambda_by_arn = lambda_.Function.from_function_arn(
    self,
    "my lambda by arn",
    my_lambda.function_arn
)
table.grant_full_access(lambda_by_arn)

The above doesn't work and the Lambda has no access whatsoever to the DynamoDB function.

If you have the DynamoDB creation in a different stack than the Lambda, you cannot do it any other way (at least, to my knowledge) than by the function_from_arn method.

I tried getting the Lambda from a different method: function_from_attributes but this resulted in the same way: No access.

2

There are 2 answers

0
fedonev On BEST ANSWER

TL;DR - The iam.Grant methods like grant_full_access *sometimes* work on externally referenced resources returned from Something.fromSomethingAttributes methods. Unfortunately, *not* for DynamoDB Table resources.

You should be seeing a warning produced by the CDK CLI when you synth the app:

[Warning at /my_stack/my_lambda_by_arn] Add statement to this resource's role: ...

This is telling you the CDK didn't grant access - do it yourself! The CDK made a design decision to warn, but not to throw an error1.

Under what conditions can an externally reference ISomething construct successfully be granted IAM privileges?

  1. The granting resource type must support Resource-based Policies (e.g. s3.Bucket, sqs.Queue), and
  2. The ISomething's role reference must be passed to Something.fromSomethingAttributes

This table summarizes what happens in various case. Your case is on the bottom right:

Method Granter has Resource Policy Granter has no Resource Policy
fromSomethingAttributes + role: IRole ✅ Role ARN added to Resource Policy UnknownPrincipal assigned, CLI Warning
fromSomethingAttributes, no role ❌ Synth error: resource imported without a role ❌ UnknownPrincipal assigned, CLI Warning
fromSomethingArn ❌ Synth error: resource imported without a role ❌ UnknownPrincipal assigned, CLI Warning

  1. You can force the CDK to fail on such synth warnings with cdk synth --strict
0
Otavio Macedo On

What from_function_arn does is import an existing Lambda function so that you can reference it from your CDK application. But it is not actually part of the application, so you can't do much with it. In particular, you can't grant any access to it.

If you have the DynamoDB creation in a different stack than the Lambda, you cannot do it any other way (at least, to my knowledge) than by the function_from_arn method.

If both stacks are in the same app, you can pass the Lambda function reference to the other stack, and CDK will know how to deal with it.