amazon-cloudfrontaws-cdkaws-lambda-edge

How to add IAM permission to Cloudfront in to be inherited by Lambda@Edge?


I am using CDK to create a Cloudfront distribution and a Lambda@Edge function to control access to it.

The problem is, the function needs permission to read a secret from the Secret Manager. It is my understanding that the function inherits the service-role of its distribution, which makes sense to me. [EDIT: I now believe that this statement might not be true. See response.]

What I don’t understand though is how to get the service-role from the distribution in order to grant it. The obviously right way to do is:

Secret.grantRead(distribution.grantPrincipal)

Obviously right, except that the type CloudFrontWebDistribution does not have a grantPrincipal.


Solution

  • I am not sure below statement is correct. Do you have any reference to prove this statement?

    It is my understanding that the function inherits the service-role of its distribution, which makes sense to me.

    Now, talking about the solution, you just need to do the following:

    1. Create an IAM Role
    2. Provide that IAM Role permissions to access secrets from the Secrets Manager
    3. Attach the IAM Role to the Lambda function

    Here is the CDK code snippet in C#, that I wrote to run Angular app with SSR on Lambda@Edge. You just need to change the IAM permissions as per your need.

    // 1.1 Create Lambda execution role
    Role lambdaExecutionRole = new Role(this, "lambda-execution-role", new RoleProps
    {
        AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
    });
    
    lambdaExecutionRole.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"));
    
    // 1.2. Do not log into CloudWatch as logs might be costly
    var policy = new Policy(this, "cw-deny-policy", new PolicyProps
    {
        Statements = new[] {
            new PolicyStatement(new PolicyStatementProps {
                Effect = Effect.DENY,
                Actions = new [] { "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" },
                Resources = new [] { "arn:aws:logs:*:*:*" }
            })
        }
    });
    
    lambdaExecutionRole.AttachInlinePolicy(policy);
    
    // 2. Edge Function
    var lambdaAtEdgeSSRFunction = new EdgeFunction(this, "ssr-lambda", new EdgeFunctionProps
    {
        MemorySize = 1024,
        Timeout = Duration.Seconds(30),
        Runtime = Runtime.NODEJS_18_X,
        Handler = "lambda.handler",
        Code = Code.FromAsset("./src/UtilityAppsCdk/DefaultArtifacts/SSREdgeLambda.zip"),
        Role = lambdaExecutionRole
    });