aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.67k stars 3.92k forks source link

[apigateway] SpecRestAPI `x-amazon-apigateway-endpoint-configuration` not usable for private API initial deployment #9684

Open IsmaelMartinez opened 4 years ago

IsmaelMartinez commented 4 years ago

It is not possible to use the swagger/openAPI x-amazon-apigateway-endpoint-configuration option in conjunction with the private endpointType.

If you specify a vpce in the endpoint configuration, you get the following:

VPCEndpoints can only be specified with PRIVATE apis. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: a2a6cebc-7004-4884-9398-0b83a384b49c)
    new SpecRestApi (/Users/ismael.martinez/projects/bitbucket/BIP/draw/draw-scheduler/node_modules/@aws-cdk/aws-apigateway/lib/restapi.ts:486:22)
...

If you deploy the stack without the x-amazon-apigateway-endpoint-configuration, it does create a usable and private API Gateway, but the vpce is not defined in the 'Settings - Endpoint configuration' section.

If you then deploy again the stack with the x-amazon-apigateway-endpoint-configuration, it does work, so this issue is only related to the initial creation of the API Gateway.

Reproduction Steps

Using the following code:

const api = new apigateway.SpecRestApi(this, 'ExampleRestApi', {
  apiDefinition: apigateway.ApiDefinition.fromInline(swaggerInline),
  endpointTypes: [apigateway.EndpointType.PRIVATE],
});

Where the swagger inline is as shown:

{
    "openapi": "3.0.1",
    "servers": [
        {
            "x-amazon-apigateway-endpoint-configuration": {
                "vpcEndpointIds": [
                    "${PPL::VPCId}"
                ]
            }
        }
    ],
    "paths": {
        "/example": {
            "get": {
                "responses": {
                    "200": {
                        "description": "200 response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/200Response"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "400 response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/400Response"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "404 response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/404Response"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "500 response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/500Response"
                                }
                            }
                        }
                    }
                },
                "x-amazon-apigateway-integration": {
                    "uri": "${PPL::LambdaAliasArn}",
                    "responses": {
                        "default": {
                            "statusCode": "200"
                        }
                    },
                    "passthroughBehavior": "when_no_match",
                    "httpMethod": "POST",
                    "contentHandling": "CONVERT_TO_TEXT",
                    "type": "aws_proxy"
                }
            }
        }
    },
    "components": {
        "schemas": {
            "200Response": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string"
                    }
                }
            },
            "400Response": {
                "type": "object",
                "properties": {
                    "errors": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "404Response": {
                "$ref": "#/components/schemas/Error"
            },
            "500Response": {
                "$ref": "#/components/schemas/Error"
            },
            "Error": {
                "type": "object",
                "properties": {
                    "errorCode": {
                        "type": "string"
                    },
                    "message": {
                        "type": "string"
                    }
                }
            }
        }
    },
    "x-amazon-apigateway-policy": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": "*",
                "Action": [
                    "execute-api:Invoke",
                    "execute-api:GET"
                ],
                "Resource": "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*",
                "Condition": {
                    "StringEquals": {
                        "aws:sourceVpce": "${PPL::VPCId}"
                    }
                }
            }
        ]
    }
}

Where the PPL::VPCId is the endpoint id and the PPL::LambdaAliasArn is the lambda alias arn.

We substitute those values dynamically but I don't thinks that is the issue.

What did you expect to happen?

I will expect to get a private API Gateway with the vpce defined in the 'Settings - Endpoint configuration' section.

What actually happened?

The deployment fails with the following message:

VPCEndpoints can only be specified with PRIVATE apis. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: a2a6cebc-7004-4884-9398-0b83a384b49c)
    new SpecRestApi (/Users/ismael.martinez/projects/bitbucket/BIP/draw/draw-scheduler/node_modules/@aws-cdk/aws-apigateway/lib/restapi.ts:486:22)
...

Environment

Other


This is :bug: Bug Report

nija-at commented 4 years ago

The requires investigation into how to correctly use x-amazon-apigateway-endpoint-configuration option in the OpenAPI definition.

rishavpaul commented 3 years ago

Is there any plan to fix this? Or perhaps enable SpecRestAPI to use the EndpointConfiguration interface ?

rishavpaul commented 3 years ago
let api = new SpecRestAPI(...)
(api.node.defaultChild as CfnRestApi).endpointConfiguration = {
  types: [EndpointType.PRIVATE],
  vpcEndpointIds: [ 'xyz' ],
};

Is a workaround until above is implemented for any else facing the same issue.

github-actions[bot] commented 2 years ago

This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

oddg commented 2 years ago

I also have a use case for the required feature. Is there a plan to address the issue?

aura-herrera-sonarsource commented 2 years ago

I am also having an issue with this. Same error, no VPC endpoint added to the REST Api after using SpecRestAPI.

kornel-kotan-sonarsource commented 2 years ago

I'm facing the same issue too. Any suggested workaround? The one indicated by @rishavpaul doesn't seem to fix the problem for me.

mattiamatrix commented 1 year ago

2023, and this is still not fixed. @RomainMuller can you help?

roypronoy commented 11 months ago

This is still open, and is very annoying. Programmatic deployments shouldn't fail like this.