[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:
- Created 3 years ago
- Comments:9 (5 by maintainers)
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.
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.”.