aws / aws/aws-cdk

(aws-apigateway): Usage of addCorsPreflight and addProxy can lead to CloudFormation drift when used with SpecRestApi

Open
#24,601 4 comments 17 reactions 0 assignees View on GitHub
@aws-cdk/aws-apigateway bug p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the bug

Hello,

I've noticed a situation that can lead to CloudFormation drift when leveraging the addCorsPreflight and addProxy method with the [SpecRestApi](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-apigateway.SpecRestApi.html) Construct.

The exact steps are here:

- T0: User creates an API definition via [SpecRestApi](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-apigateway.SpecRestApi.html) attribute [ApiDefinition](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-apigateway.ApiDefinition.html)
- T1: User adds some resources via other CDK methods such as [addCorsPreflight](https://docs.aws.amazon.com/cdk/api/v1/docs/aws-apigateway-readme.html#cross-origin-resource-sharing-cors) and [addProxy](https://docs.aws.amazon.com/cdk/api/v1/docs/aws-apigateway-readme.html#proxy-routes)
- T2: User updates the Open API definition and redeploys stack
- T3: The API Gateway resources created at T1 disappear in API Gateway, but still exist in the template. Therefore causing CloudFormation Drift.

The documentation is also kind of confusing on this situation. In one area it says[ "All Resources and Methods need to be defined as part of the OpenAPI specification file, and cannot be added via the CDK." ](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-apigateway.SpecRestApi.html)

In the [example](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-apigateway.SpecRestApi.html#example) though, it does show new methods being added after also using the ApiDefinition attribute which conflicts with the earlier message.

Also, [here]( https://docs.aws.amazon.com/cdk/api/v1/docs/aws-apigateway-readme.html#openapi-definition) it states that It is possible to use the addResource() API to define additional API Gateway Resources. This is true but users can get themselves in the above situation if they update the Open API definition in a future deployment.

### Expected Behavior

I would expect that the addProxy and addCorsPreflight API resources to remain even after I change the OpenApi definition of the SpecRestApi.

### Current Behavior

After I change the OpenApi definition and redeploy, the resources generated by the addCorsPreflight and addProxy methods are overriden in API Gateway but still exist in the template. Also when I check for CloudFormation drift, I see the stack has drifted.

### Reproduction Steps

Steps:
1. Run the below code for a stack and deploy
2. Change the open API definition in some way
3. Redeploy
4. Check for CloudFormation drift and see that the proxy and OPTIONS method on root have disappeared

```
// Create regular pets api based on template
const api = new apigateway.SpecRestApi(this, 'pets-api', {
apiDefinition: apigateway.ApiDefinition.fromInline({
openapi: '3.0.2',
paths: {
'/pets': {
get: {
'responses': {
200: {
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/Empty',
},
},
},
},
},
'x-amazon-apigateway-integration': {
responses: {
default: {
statusCode: '200',
},
},
requestTemplates: {
'application/json': '{"statusCode": 200}',
},
passthroughBehavior: 'when_no_match',
type: 'mock',
},
},
},
},
components: {
schemas: {
Empty: {
title: 'Empty Schema',
type: 'object',
},
},
},
})
});

const preflightOptionsTest = {
allowCredentials: true,
allowMethods: ['POST', 'GET'],
allowOrigins: [
'https://example.website',
],
};

// use addCorsPreflight
api.root.addCorsPreflight(preflightOptionsTest);

// use addProxy
const corsProxyMethodTest = api.root.addProxy({
anyMethod: false,
});

corsProxyMethodTest.addCorsPreflight(preflightOptionsTest);

```

### Possible Solution

As a suggested fix, I would recommend modifying the internal implementations of addCorsPreflight and addProxy to modify the OpenAPI document rather than creating the resources outside of the OpenApi document when the user is using SpecRestApi

I would really like to use addCorsPreflight and addProxy methods for my SpecRestApi given that they greatly simplify CORS integration steps.

### Additional Information/Context

_No response_

### CDK CLI Version

2.43.0 (build 487870a)

### Framework Version

_No response_

### Node.js Version

v18.13.0

### OS

macOS Monterey 12.6.3

### Language

Typescript

### Language Version

_No response_

### Other information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the SpecRestApi construct and the addCorsPreflight and addProxy entry points described in the reproduction. Re-run the TypeScript example, update its OpenAPI definition, redeploy, and inspect the resulting API Gateway resources and CloudFormation drift. Done means those resources remain present after the definition changes and the reported drift no longer occurs.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
api, cloud, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.