Skip to content

OpenApiGatewayToLambda: "CustomResource attribute error: Vendor response doesn't contain TemplateOutputKey attribute" #1344

@paulwehage

Description

@paulwehage

I'm currently trying to deploy my OpenApiGatewayToLambda, but getting the error mentioned in the title. The error indicates that the OpenApiGatewayToLambdaApiTemplateWriterCustomResource object is causing the issue. It used to work some days ago, but i already reupdated all package versions to the versions that used to work. Without success. After some investigation i found out that the TemplateOutputKey is generated in the template-writer-custom-resource from aws-solutions-constructs:

const templateOutputKey = crypto.randomBytes(32).toString('hex');

and then used in the responseData:

responseData = { TemplateOutputKey: templateOutputKey };

This lambda tries to send data to the cdk asset bucket that gets generated while bootstrapping. When going into the lambdas logs i found this error:

"User: arn:aws:sts::xxx:assumed-role/api-gateway-stack-OpenApiGatewayToLambda/api-gateway-stack-OpenApiGatewayToLambda is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::cdk-assets-xxx-eu-west-1" with an explicit deny in a resource-based policy"

When looking into the Bucket Policy, i see that it only allows PutObject if kms headers are passed.

Looking back to the template-writer-custom-resource (Lambda) it sends the data to S3 without encryption:

await s3Client.send(new PutObjectCommand({ Bucket: templateOutputBucket, Key: templateOutputKey, Body: template // ❌ Missing: ServerSideEncryption: 'aws:kms' }));

Has anybody an idea what i'm missing out of a sudden? Do i have to adapt the policies?

Reproduction Steps

Here is all my Constructs Code. I already checked if some properties are not passed properly, but this isn't the case. It just does not deploy. I also checked my OpenAPI Spec. It is also not the problem.

    // For private endpoints, use proper IVpcEndpoint[] array
    if (isPrivate && vpcEndpointService) {
        endpointConfiguration = {
            types: [EndpointType.PRIVATE],
            vpcEndpoints: [vpcEndpointService],
        };
    }

    // Create the API Gateway
    const apiGatewayConstruct = new OpenApiGatewayToLambda(this, 'OpenApiGatewayToLambda', {
        apiDefinitionAsset,
        apiGatewayProps: {
            deployOptions: {
                stageName: props.stageName,
                loggingLevel: MethodLoggingLevel.INFO,
                metricsEnabled: true,
                tracingEnabled: true,
                accessLogDestination: accessLogDestination,
                accessLogFormat: AccessLogFormat.clf(),
                variables: {
                    ...(authorizerLambda && { authorizerName: authorizerLambda.functionName }),
                    dispatcherLambdaName: props.dispatcherLambdaName,
                    getLambdaName: props.getLambdaName,
                    region: Stack.of(this).region,
                    accountId: Stack.of(this).account,
                },
            },
            restApiName: `${props.apiName}-${isPrivate ? 'private' : 'public'}`,
            description: `API Gateway for managing AWS Workspaces (${props.apiVersion}) - ${isPrivate ? 'Private' : 'Public'}`,
            endpointConfiguration: endpointConfiguration,
            // Resource policy for private API Gateway
            ...(isPrivate && {
                policy: this.createPrivateApiResourcePolicy(props.vpcEndpointId),
            }),
        },
        apiIntegrations: [
            {
                id: 'DispatcherLambda',
                existingLambdaObj: LambdaFunction.fromFunctionName(
                    this,
                    'DispatcherLambda',
                    props.dispatcherLambdaName,
                ) as LambdaFunction,
            },
            {
                id: 'GetLambda',
                existingLambdaObj: LambdaFunction.fromFunctionName(
                    this,
                    'GetLambda',
                    props.getLambdaName,
                ) as LambdaFunction,
            },
        ],
    });`

Error Log

CustomResource attribute error: Vendor response doesn't contain TemplateOutputKey attribute in object arn:aws:cloudformation:eu-west-1:xxx:stack/vClient-api-gateway-stack-dev/f15614b0-52a4-11
f0-ae21-02f95d261deb|OpenApiGatewayToLambdaApiTemplateWriterCustomResource957D1BA4|c7cf2bdd-f83c-40ba-be5a-0925fafeb017

Environment

  • CDK CLI Version : 2.1006.0
  • CDK Framework Version: 2.193.0
  • AWS Solutions Constructs Version: 2.85.2
  • **OS : MACOS
  • Language : Typescript, English

This is 🐛 Bug Report

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds-triageThe issue or PR still needs to be triaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions