aws-amplifyaws-cdkaws-cloudformation-custom-resource

Create a custom resource with AWS Amplify and CDK


I'm trying to create a custom resource in AWS Amplify, using AWS CDK. And, I'm trying to use an existing lambda function as a provider event handler.

When I do amplify push the resource creation fails with no useful information. What am I doing wrong here? How can I troubleshoot this?

import * as cdk from '@aws-cdk/core';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import * as cr from "@aws-cdk/custom-resources";
import * as logs from "@aws-cdk/aws-logs";
import * as lambda from '@aws-cdk/aws-lambda';

import { AmplifyDependentResourcesAttributes } from "../../types/amplify-dependent-resources-ref"

export class cdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
    super(scope, id, props);
    /* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
    new cdk.CfnParameter(this, 'env', {
      type: 'String',
      description: 'Current Amplify CLI env name',
    });

    const dependencies: AmplifyDependentResourcesAttributes = AmplifyHelpers.addResourceDependency(this,
      amplifyResourceProps.category,
      amplifyResourceProps.resourceName,
      [{
        category: "function",
        resourceName: "myFunction" 
      }] 
    );


    const myFunctionArn = cdk.Fn.ref(dependencies.function.myFunction.Arn);
    const importedLambda = lambda.Function.fromFunctionArn(this, "importedLambda", myFunctionArn);
    
    const provider = new cr.Provider(this, "MyCustomResourceProvider", {
      onEventHandler: importedLambda,
      logRetention: logs.RetentionDays.ONE_DAY,
    })

    new cdk.CustomResource(this, "MyCustomResource", {
      serviceToken: provider.serviceToken
    })
  }
}

Here's the error I get:

CREATE_FAILED custommyCustomResourceXXXX AWS::CloudFormation::Stack Parameters: [AssetParametersXXXX, .....] must have values.


Solution

  • I got a response from AWS support team. It looks like the AssetParameters error is caused by the fact that Amplify CLI currently doesn't support a high level construct of Custom Resource Provider inside the custom resource category in Amplify CLI. The resource should be created this way:

    import * as cdk from '@aws-cdk/core';
    import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
    import * as lambda from '@aws-cdk/aws-lambda';
    
    import { AmplifyDependentResourcesAttributes } from "../../types/amplify-dependent-resources-ref"
    
    export class cdkStack extends cdk.Stack {
      constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
        super(scope, id, props);
        /* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
        new cdk.CfnParameter(this, 'env', {
          type: 'String',
          description: 'Current Amplify CLI env name',
        });
    
        const dependencies: AmplifyDependentResourcesAttributes = AmplifyHelpers.addResourceDependency(this,
          amplifyResourceProps.category,
          amplifyResourceProps.resourceName,
          [{
            category: "function",
            resourceName: "myFunction" 
          }] 
        );
    
    
        const myFunctionArn = cdk.Fn.ref(dependencies.function.myFunction.Arn);
        const importedLambda = lambda.Function.fromFunctionArn(this, "importedLambda", myFunctionArn);
        
        new cdk.CustomResource(this, "MyCustomResource", {
          serviceToken: importedLambda.functionArn
        })
      }
    }