Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: Tags aspect breaks API Gateway V2 that uses OpenAPI spec #28552

Closed
sam-goodwin opened this issue Jan 3, 2024 · 4 comments
Closed

core: Tags aspect breaks API Gateway V2 that uses OpenAPI spec #28552

sam-goodwin opened this issue Jan 3, 2024 · 4 comments
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. effort/medium Medium work item – several days of effort p2

Comments

@sam-goodwin
Copy link
Contributor

Describe the bug

I am creating an API Gateway V2 using a hard-coded OpenAPI spec.

I am then adding tags to my resources using the Tags.of(..).add(..) pattern (as is recommended).

This results in an error in CloudFormation:

|  Site service/Gateway AWS::ApiGatewayV2::Api CREATE_FAILED Resource handler returned message: "Redundant fields [tags={"sst:app":"sst-nextjs","sst:stage":"samgoodwin"}] provided when either Body or BodyS3Location is not empty (Service: null; Status Code: 0; Error Code: null; Request ID: null; Proxy: null) (Service: null; Status Code: 404; Error Code: BadRequestException; Request ID: null; Proxy: null)" (RequestToken: 6c87e720-6a2d-eb8d-64fe-6792d8a2729d, HandlerErrorCode: GeneralServiceException)

Looks like there is an edge case where tags are not supported when using Body to specify an OpenAPI spec.

Expected Behavior

Adding tags to an API Gateway V2 that uses OpenAPI should not modify the resource configuration in a way that is incompatible with CloudFormation.

Current Behavior

Tags are added to the API GW resource which then fails to deploy.

Reproduction Steps

import * as cdk from '@aws-cdk/core';
import * as apigateway from '@aws-cdk/aws-apigatewayv2';
import * as lambda from '@aws-cdk/aws-lambda';

export class ApiGatewayStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const mockLambda = new lambda.Function(this, 'MockLambda', {
      runtime: lambda.Runtime.NODEJS_14_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async (event) => {
          return {
            statusCode: 200,
            body: JSON.stringify({ message: 'Hello from Lambda!' }),
          };
        };
      `),
    });

    const openApiSpec = {
      openapi: '3.0.1',
      info: {
        title: 'backend',
        version: '1'
      },
      paths: {
        '/$default': {
          'x-amazon-apigateway-any-method': {
            'isDefaultRoute': true,
            'x-amazon-apigateway-integration': {
              'connectionType': 'INTERNET',
              'httpMethod': 'POST',
              'payloadFormatVersion': '2.0',
              'type': 'AWS_PROXY',
              'uri': `arn:aws:apigateway:${this.region}:lambda:path/2015-03-31/functions/${mockLambda.functionArn}/invocations`
            }
          }
        }
      }
    };

    new apigateway.CfnApi(this, 'MyApi', {
      name: 'MyApi',
      protocolType: 'HTTP',
      body: openApiSpec
    });
  }
}

const app = new cdk.App();
const stack = new ApiGatewayStack(app, "stack");

cdk.Tags.of(stack).add("tag-name", "tag-value");

Possible Solution

Perhaps the tags should be added to the spec or not added at all?

Additional Information/Context

No response

CDK CLI Version

2.117.0 (build 59d9b23)

Framework Version

2.110.1

Node.js Version

v20.9.0

OS

Mac OS 13.1

Language

TypeScript

Language Version

5

Other information

No response

@sam-goodwin sam-goodwin added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jan 3, 2024
@github-actions github-actions bot added the @aws-cdk/core Related to core CDK functionality label Jan 3, 2024
@pahud
Copy link
Contributor

pahud commented Jan 3, 2024

Cloudformation does not allow you to specify properties like Tags, name or protocolType when Body is specified.

Resource handler returned message: "Redundant fields [name="MyApi", protocolType="HTTP"] provided when either Body or BodyS3Location is not empty (Service: n
ull; Status Code: 0; Error Code: null; Request ID: null; Proxy: null) (Service: null; Status Code: 404; Error Code: BadRequestException; Request ID: null; Pr
oxy: null)" (RequestToken: 337ab473-bffe-9a3b-6251-038168e990d5, HandlerErrorCode: GeneralServiceException)

I think you will need something like this

  new apigwv2.CfnApi(this, 'MyApi', {
    body: openApiSpec
  });

cdk.Tags.of(stack).add("tag-name", "tag-value", {
    excludeResourceTypes: ['AWS::ApiGatewayV2::Api'],
});

And probably specify your tags in x-amazon-apigateway-tag-value instead.

Let me know if it works for you.

@pahud
Copy link
Contributor

pahud commented Jan 3, 2024

Full sample

export class DemoStack extends MyStack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);


    const mockLambda = new lambda.Function(this, 'MockLambda', {
      runtime: lambda.Runtime.NODEJS_16_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async (event) => {
          return {
            statusCode: 200,
            body: JSON.stringify({ message: 'Hello from Lambda!' }),
          };
        };
      `),
    });

    const openApiSpec = {
      openapi: '3.0.1',
      info: {
        title: 'backend',
        version: '1'
      },
      tags: [
        {
          "name": "Owner",
          "x-amazon-apigateway-tag-value": "Admin"
        },
        {
          "name": "Prod"
        }
      ],
      paths: {
        '/$default': {
          'x-amazon-apigateway-any-method': {
            'isDefaultRoute': true,
            'x-amazon-apigateway-integration': {
              'connectionType': 'INTERNET',
              'httpMethod': 'POST',
              'payloadFormatVersion': '2.0',
              'type': 'AWS_PROXY',
              'uri': `arn:aws:apigateway:${this.region}:lambda:path/2015-03-31/functions/${mockLambda.functionArn}/invocations`
            }
          }
        }
      }
    };

    new apigwv2.CfnApi(this, 'MyApi', {
      body: openApiSpec
    });
  }
}

app.ts

const stack = new DemoStack(app, 'DemoStack4', { env });

cdk.Tags.of(stack).add("tag-name", "tag-value", {
    excludeResourceTypes: ['AWS::ApiGatewayV2::Api'],
});

And you see the Tags from the console

image

@pahud pahud added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. p2 effort/medium Medium work item – several days of effort and removed needs-triage This issue or PR still needs to be triaged. labels Jan 3, 2024
@sam-goodwin
Copy link
Contributor Author

Awesome, thanks for finding the working solution!

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jan 4, 2024
@pahud pahud closed this as completed Jan 4, 2024
Copy link

github-actions bot commented Jan 4, 2024

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/core Related to core CDK functionality bug This issue is a bug. effort/medium Medium work item – several days of effort p2
Projects
None yet
Development

No branches or pull requests

2 participants