[apigateway] SpecRestAPI `x-amazon-apigateway-endpoint-configuration` not usable for private API initial deployment
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
- CLI Version : 1.57.0
- Framework Version: 1.57.0
- Node.js Version: 10.22.0
- OS : MAC 10.15.6
- Language (Version): TypeScript (3.8.2)
Other
This is :bug: Bug Report
The requires investigation into how to correctly use x-amazon-apigateway-endpoint-configuration option in the OpenAPI definition.
Is there any plan to fix this? Or perhaps enable SpecRestAPI to use the EndpointConfiguration interface ?
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.
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.
I also have a use case for the required feature. Is there a plan to address the issue?
I am also having an issue with this. Same error, no VPC endpoint added to the REST Api after using SpecRestAPI.
I'm facing the same issue too. Any suggested workaround? The one indicated by @rishavpaul doesn't seem to fix the problem for me.
2023, and this is still not fixed. @RomainMuller can you help?
This is still open, and is very annoying. Programmatic deployments shouldn't fail like this.
I was unable to reproduce the issue. I used the following code, which is mostly the same code as the one in the reproduction step with some additional pieces that's missing to make it work. The solution worked without any problems, and I confirmed that the endpoint is displayed in the API Settings page of the AWS Console.
const vpc = new Vpc(this, 'Vpc', {
})
const apiGatewayEndpoint = new InterfaceVpcEndpoint(this, 'ApiGatewayEndpoint', {
vpc,
service: InterfaceVpcEndpointAwsService.APIGATEWAY,
});
const lambdaFunction = new Function(this, 'ExampleFunction', {
runtime: Runtime.NODEJS_18_X,
handler: 'index.handler',
code: Code.fromInline("foo")
});
const swaggerInline = {
"openapi": "3.0.1",
"servers": [
{
"x-amazon-apigateway-endpoint-configuration": {
"vpcEndpointIds": [
`${apiGatewayEndpoint.vpcEndpointId}`
]
}
}
],
"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": `arn:aws:apigateway:${this.region}:lambda:path/2015-03-31/functions/${lambdaFunction.functionArn}/invocations`,
"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":
`${apiGatewayEndpoint.vpcEndpointId}`
}
}
}
]
}
}
const api = new SpecRestApi(this, 'ExampleRestApi', {
apiDefinition: ApiDefinition.fromInline(swaggerInline),
endpointTypes: [EndpointType.PRIVATE],
});
This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.