1

I am implementing a custom resource in CDK. In the success scenario all works well. The CDK stack is deployed and the custom resource calls the Lambda function it should invoke using the construct AwsCustomResource. The stack deployed to the account finishes in a success state. I can also affirm that the function ran correctly as the log shows this.account printed from the event object. However when I throw an error in the function called by AwsCustomResource, I would expect it stack creation to fail. However it still succeeds.

The body of the function called by the AwsCustomResource is:

import { Handler } from 'aws-lambda';

export const handler: Handler = async (event, context) => {

    console.log(event);

    return new Error("ERROR FROM REMOTE FUNCTION");

};

I also tried:

import { Handler } from 'aws-lambda';

export const handler: Handler = async (event, context) => {

    console.log(event);

    throw new Error("ERROR FROM REMOTE FUNCTION");

};

My implementation of AwsCustomResource in the stack is (please note the the function is first deployed and then called by the functions ARN):

import * as cdk from 'aws-cdk-lib';
import { custom_resources as cr } from "aws-cdk-lib";
import { aws_iam as iam } from "aws-cdk-lib";

export class Test extends cdk.Stack {

  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const crRole = new iam.Role(this, 'MyRole', {
      assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')
      ]
    });

    const myCustomResource = new cr.AwsCustomResource(this, 'MyCustomResource', {
      onUpdate: {
        service: 'Lambda',
        action: 'invoke',
        parameters: {
          FunctionName: 'ARN_TO_THE_FUNCTION',
          Payload: JSON.stringify({
            account: this.account
          })
        },
        physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()),
      },
      role: crRole,
    });

  }
}

What am I missing here?

gshpychka
  • 8,523
  • 1
  • 11
  • 31
SomeDutchGuy
  • 2,249
  • 4
  • 16
  • 42

1 Answers1

0

AwsCustomResource is a custom resource that calls an AWS API. In your case, its only task is to invoke a lambda - and it does that successfully. Your lambda is not part of the custom resource.

To make a lambda-backed custom resource, use the Provider construct.

Here is an example from the docs:

declare const onEvent: lambda.Function;
declare const isComplete: lambda.Function;
declare const myRole: iam.Role;
const myProvider = new cr.Provider(this, 'MyProvider', {
  onEventHandler: onEvent,
  isCompleteHandler: isComplete,
  logRetention: logs.RetentionDays.ONE_DAY,
  role: myRole,
  providerFunctionName: 'the-lambda-name',   // Optional
});

Your function will have to handle different event payloads, such as Create/Update/Delete, return the physical ID, etc.

gshpychka
  • 8,523
  • 1
  • 11
  • 31