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.

(cloudfront, lambda): cyclic dependency for Lambda@Edge when using role

See original GitHub issue

When using the CloudFront EdgeFunction with a role specified by the developer, a cyclic dependency error occurs.

Reproduction Steps

import * as cloudfront from "@aws-cdk/aws-cloudfront";
import * as origins from "@aws-cdk/aws-cloudfront-origins";
import * as lambda from "@aws-cdk/aws-lambda";
import * as core from "@aws-cdk/core";
import * as iam from "@aws-cdk/aws-iam";

import { Stack, StackProps } from "@_org_/lib-infra-common";

export class EdgeLambdaStack extends Stack {
  constructor(scope: core.Construct, customProps: StackProps, stackProps: core.StackProps = {}) {
    super(scope, customProps, stackProps);

    const edgeLambdaRole = new iam.Role(this, "LambdaRole", {
      roleName: core.PhysicalName.GENERATE_IF_NEEDED,
      assumedBy: new iam.CompositePrincipal(
        new iam.ServicePrincipal("lambda.amazonaws.com"),
        new iam.ServicePrincipal("edgelambda.amazonaws.com"),
      ),
       // ...any sort of managed policy (not needed to reproduce)
    });

    const myFunc1 = new cloudfront.experimental.EdgeFunction(this, "MyFunction1", {
      runtime: lambda.Runtime.NODEJS_10_X,
      handler: "index.handler",
      code: lambda.Code.fromInline("return"),
      role: edgeLambdaRole,
    });

    new cloudfront.Distribution(this, "myDist", {
      defaultBehavior: {
        origin: new origins.HttpOrigin("www.example.com"),
        edgeLambdas: [
          {
            functionVersion: myFunc1.currentVersion,
            eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
          },
        ],
      },
    });
  }
}

What did you expect to happen?

A Lambda function would be created in the us-east-1 region, and the role would be created in IAM globally.

What actually happened?

Error: 'Dev-Marketing-EdgeLambdaStack' depends on 'edge-lambda-stack-c8c09337b87f7807acc2002239aca2181ae1916d18' (dependency added using stack.addDependency()). Adding this dependency ("edge-lambda-stack-c8c09337b87f7807acc2002239aca2181ae1916d18/MyFunction1/Resource" depends on "Dev-Marketing-EdgeLambdaStack/LambdaRole/Resource") would create a cyclic reference.
    at Stack._addAssemblyDependency (/Users/arjunnaha/Developer/_org_/web-marketing/node_modules/@aws-cdk/core/lib/stack.ts:724:13)
    at Object.addDependency (/Users/arjunnaha/Developer/_org_/web-marketing/node_modules/@aws-cdk/core/lib/deps.ts:52:20)
    at CfnFunction.addDependsOn (/Users/arjunnaha/Developer/_org_/web-marketing/node_modules/@aws-cdk/core/lib/cfn-resource.ts:245:5)
    at Object.prepareApp (/Users/arjunnaha/Developer/_org_/web-marketing/node_modules/@aws-cdk/core/lib/private/prepare-app.ts:26:16)
    at Object.synthesize (/Users/arjunnaha/Developer/_org_/web-marketing/node_modules/@aws-cdk/core/lib/private/synthesis.ts:24:3)
    at App.synth (/Users/arjunnaha/Developer/_org_/web-marketing/node_modules/@aws-cdk/core/lib/stage.ts:188:23)
    at process.<anonymous> (/Users/arjunnaha/Developer/_org_/web-marketing/node_modules/@aws-cdk/core/lib/app.ts:123:45)
    at Object.onceWrapper (node:events:483:26)
    at process.emit (node:events:376:20)
    at process.EventEmitter.emit (node:domain:470:12)

Environment

  • CDK CLI Version: 1.90.1 (build 0aee440)
  • Framework Version: 1.90.1
  • Node.js Version: v15.5.0
  • OS: macOS Big Sur 11.2.1
  • Language (Version): TypeScript (4.1.3)

This is 🐛 Bug Report

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
njlynchcommented, Mar 17, 2021

@asnaseer-resilient -

I thought my code is written such that the edge lambda function is indeed creating the role role: new cdkIam.Role(this, ‘LambdaAtEdgeRole’, { roleName: CDK_UTILS.resourceName(‘cf-lae-role’), assumedBy: new cdkIam.CompositePrincipal(new cdkIam.ServicePrincipal(‘lambda.amazonaws.com’), new cdkIam.ServicePrincipal(‘edgelambda.amazonaws.com’)) }),

No, in the above example, you are still creating the role explicitly and passing it to the Function. For the function to create the role, you need to leave the role parameter as undefined; then once the Function has been created, use lambdaAtEdgeFunction.role to access the role and modify the permissions as required.

1reaction
njlynchcommented, Mar 1, 2021

I think this is likely a permanent work-around, until someone more clever than me comes around with a solution. 😃

Detecting that the Role passed in might cause a circular dependency, then creating a third stack, then re-parenting the role into a new stack, is not something I would expect (nor really want) the construct to do. I can imagine all sorts of unintended consequences with that approach.

I’m going to close this, but feel free to comment (and @ me) if you have any follow-ups.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Fix the circular dependency between AWS Lambda ...
When you create the Lambda permission, you must associate the permission with an AWS Principal and SourceARN (in this case, a target group)....
Read more >
Serverless Framework - Lambda@Edge Deployment for a ...
Any help on how to get lambda edge works with predefined cloud front through the serverless framework? AWS Collective. aws-lambda · amazon- ...
Read more >
serverless/serverless - Gitter
It's saying that the function you're targeting with that aws lambda permission doesn't exist. "Why doesn't it exist" could be a ...
Read more >
@aws-cdk/aws-lambda-event-sources - Package Manager
You can use event source mappings to process items from a stream or queue in services that don't invoke Lambda functions directly. Lambda...
Read more >
How do I structure my Terraform projects? - The Consulting CTO
Or you can learn how to bootstrap your AWS environments with fenna . ... that sets up HTTP Basic Auth for S3 objects...
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