typescriptamazon-web-servicesaws-lambdaaws-cdk

Fetch ARN from new Lamda using CDK


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.


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],
      }),
    });