I'm using CDK with Typescript and I'm trying to fetch the ARN of a newly created lambda. I can fetch the ARN of a new Role within the same stack, however I think the issue is that I'm trying to set the environment on the same lambda that I'm referencing. Here is my example:
const lambdaRole = new iam.Role(this,...)
const sts = new lambda.DockerImageFunction(this,...) {
...
environment: {
TARGET_ARN: sts.functionArn // Can't do this because 'sts' isn't defined yet.
}
//This throws a circular dependency error
sts.addEnvironment('TARGET_ARN', sts.functionArn)
//Also tried this, but get the following error making me think that 'sts.functionName' isn't available yet. ValidationError: Template error: every Fn::GetAtt object requires two non-empty parameters, the resource name and the resource attribute
const lambdaARN = cdk.Fn.getAtt( sts.functionName, "Arn").toString();
sts.addEnvironment('TARGET_ARN', lambdaARN)
//This works fine, possibly because it comes from a different component?
sts.addEnvironment('ROLE_ARN', lambdaRole.roleArn)
At the end of the day, I want to be able to pass the Lambda ARN into itself as an environment variable. I don't want to store it in the param store, but may have to if there's no easy solution.
You can use a custom resource for that, it will process the update using a sdk call once the lambda is created:
const lambdaRole = new iam.Role(this,...)
const sts = new lambda.DockerImageFunction(this,...) {
...
}
const updateEnvVarSdkCall: AwsSdkCall = {
service: 'Lambda',
action: 'updateFunctionConfiguration',
parameters: {
FunctionName: sts.functionArn,
Environment: {
Variables: {
TARGET_ARN: sts.functionArn,
},
},
},
physicalResourceId: PhysicalResourceId.of(sts.functionArn),
};
new AwsCustomResource(this, 'UpdateEnvVar', {
onCreate: updateEnvVarSdkCall,
onUpdate: updateEnvVarSdkCall,
policy: AwsCustomResourcePolicy.fromSdkCalls({
resources: [sts.functionArn],
}),
});