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.

[aws-lambda] Circular dependency when adding environment variables

See original GitHub issue

❓ General Issue

The Question

How can I break a circular dependency when adding (self-referencing) environment variables to a lambda function?

I am conducting some experiments with a) recursive calls (one lambda invoking itself) and b) calling other lambdas deployed within the same stack. I wanted to invoke them at runtime by adding the function name as an environment variable in each of the lambdas. This is a minimal example:

import * as cdk from '@aws-cdk/core';
import * as _ from 'lodash';
import lambda = require('@aws-cdk/aws-lambda');
import path = require('path');

export class LambdaEnvVarsStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    let dataAccessLambdas: Array<lambda.Function> = [];
    let dataAccessEnvVars: { [k: string]: string } = {};

    let findLambda = new lambda.Function(this, 'CdkExampleDaoFind', {
      runtime: lambda.Runtime.NODEJS_10_X,
      code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'),
      handler: 'find.handler',
    });
    dataAccessLambdas.push(findLambda);
    dataAccessEnvVars['DAO_FIND'] = findLambda.functionName;

    let getAllLambda = new lambda.Function(this, 'CdkExampleDaoGetAll', {
      runtime: lambda.Runtime.NODEJS_10_X,
      code: lambda.Code.fromInline('exports.handler = function(event, ctx, cb) { return cb(null, "hi"); }'),
      handler: 'get-all.handler',
    });
    dataAccessLambdas.push(getAllLambda);
    dataAccessEnvVars['DAO_GET_ALL'] = getAllLambda.functionName;

    _.each(dataAccessEnvVars, (envVarValue, envVarKey) => {
      _.each(dataAccessLambdas, function (dataAccessLambda) {
        dataAccessLambda.addEnvironment(envVarKey, envVarValue);
      });
    });

    // same problem here
    // findLambda.addEnvironment("DAO_FIND", findLambda.functionName);
  }
}

This creates a circular dependency (output from cdk deploy):

LambdaEnvVarStack: creating CloudFormation changeset...

❌  LambdaEnvVarStack failed: ValidationError: Circular dependency between resources: [CdkExampleDaoFind97AC4CCA, CdkExampleDaoGetAll6F857F77]
Circular dependency between resources: [CdkExampleDaoFind97AC4CCA, CdkExampleDaoGetAll6F857F77]

I see that this is caused at cloudformation validation time and sort of understand the underlying dependency-issue, but have no clue on how I could work around it (I’ve tried a few things, see below). I am just a bit confused because essentially it’s just a string that I want to inject as an environment variable into the lambda. I am aware that other (architectural) solution approaches are possible, but it’s experimental and I am curious how it could be solved.

All my efforts so far led to nowhere. Thanks for any hints!

Environment

  • CDK CLI Version: 1.67.0 (build 2b4dd71)
  • Module Version: 1.67.0
  • Node.js Version: v10.15.1
  • OS: Windows 10
  • Language (Version): TypeScript (4.0.3)

Other information

I’ve also tried other things:

  • create a separate stack to inject the env vars and .addDependency to the one containing the lambdas
  • various (partially strange) ideas to clone the env var strings and iterating differently
  • excluding the ‘own’ env var and only inject the ‘others’
  • tried my luck with CfnJson
  • considered using the Fn class (but sounds too complicated for this use case)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
michaelwilescommented, Oct 23, 2020

The reality is the name of the lambda is only going to be known at deployment time and it is at deployment time that the env vars are set.

A child stack to set the env var might work if you make sure to only deploy the child stack (exclusive deploy). Though you might need to export the variable from the one lambda into the other in order to break the direct link.

Another option would be to store the name in say parameter store and fetch it from the lambda. Or I am sure the lambda can ask for it’s own name.

I think from the code you’re setting the the lambda names both on the same lambda and on the other lambda. You should at least be able to set the name of lambda A in lambda B and the name of lambda B in lambda A.

0reactions
SamStephenscommented, Apr 29, 2022

@SamStephens I already have the function name in my lambda handler, but still I get error while adding env from API gateway to s3 listener.

This isn’t a help forum, it’s a place for reporting bugs. Unless you’re saying that the error is caused by a bug in the CDK, you are better off going to https://stackoverflow.com/ or a similar website, and asking for help, with a detailed explanation of what you have done, and what the error message you are seeing is. https://stackoverflow.com/help/how-to-ask has a good explanation of how to ask for help effectively.

If what you are seeing is actually a bug in the CDK, you should create a new issue, rather than comment on this closed issue. As the text says above, “Comments on closed issues are hard for our team to see.”.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Fix the circular dependency between AWS Lambda ...
How do I fix the circular dependency between an AWS Lambda permission and target group resources in AWS CloudFormation?
Read more >
Referencing lambda environment variable in Cloudformation ...
I want to add an environment variable inside the Lambda function for ... The problem is that this throws a circular dependency error...
Read more >
Resolving circular dependencies in CDK Constructs/CFN ...
If these two elements reside on different stacks, CDK will complain that there is a circular reference among them.
Read more >
Avoiding Circular References - Educative.io
Learn how to avoid circular references by setting up a ​custom IAM policy. ... The conversion function also needs permissions to read from...
Read more >
Exploring how to solve circular dependencies | Pulumi Blog
Therefore, we can't express a circular dependency in this way. ... environment: { variables: { OPPONENT_FN_NAME: currentStack .
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