API Gateway & Lambda: Unable to delete Lambda function from AWS API Gateway (Lambda still in use by API Gateway)
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
What I'm trying to do, is remove a Lambda Function from the API Gateway. I don't want to delete the whole Lambda Function itself (though that's not even possible when I try to).
I try to do this by simply commenting out the line of code that adds the Lambda Function to the API Gateway.
Here is my ApiGatewayStack:
```typescript
import { Stack } from "aws-cdk-lib";
import { Construct } from "constructs";
import { StackPropsConfig } from "../config/stackPropsConfig";
import { Deployment, DomainName, EndpointType, LambdaIntegration, RestApi, Stage } from "aws-cdk-lib/aws-apigateway";
import { IHostedZone } from "aws-cdk-lib/aws-route53";
import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
interface ApiGatewayProps extends StackPropsConfig {
hostedZone: IHostedZone;
certificate: ICertificate;
testLambda: LambdaIntegration;
createPost: LambdaIntegration;
getPost: LambdaIntegration;
}
export class ApiGatewayStack extends Stack {
public readonly customDomain: DomainName;
constructor(scope: Construct, id: string, props: ApiGatewayProps) {
super(scope, id, props);
const apiGateway = new RestApi(this, `butlai-api-gateway-${props.config.ENV}`, {
deploy: false
});
this.customDomain = apiGateway.addDomainName(`butlai-api-gateway-custom-domain-${props.config.ENV}`, {
domainName: props.config.ENV_URL,
certificate: props.certificate,
endpointType: EndpointType.EDGE,
});
// Explicitly create a deployment for v1
const deploymentV1 = new Deployment(this, `butlai-api-deployment-v1-${props.config.ENV}-${Date.now()}`, {
api: apiGateway,
retainDeployments: true,
});
// Create a stage for v1
new Stage(this, `butlai-api-stage-v1-${props.config.ENV}`, {
deployment: deploymentV1,
stageName: 'v1'
});
// Create resources and methods for v1
const postsResourcesV1 = apiGateway.root.addResource("posts");
postsResourcesV1.addMethod("POST", props.createPost);
const postResourcesV1 = postsResourcesV1.addResource("{id}");
postResourcesV1.addMethod("GET", props.getPost);
postResourcesV1.addMethod("DELETE", props.testLambda);
}
}
```
And this is my `Launcher.ts` file:
```typescript
import { App } from "aws-cdk-lib"
import { NetworkStack } from "./stacks/NetworkStack";
import { AppConfig } from "./config/types";
import { loadConfig } from "./config/loadConfig";
import { DataStack } from "./stacks/DataStack";
import { LambdaStack } from "./stacks/LambdaStack";
import { ApiGatewayStack } from "./stacks/ApiGatewayStack";
import { CertificateStack } from "./stacks/CertificateStack";
import { Route53Stack } from "./stacks/Route53Stack";
import { ApiGatewayDomain } from "aws-cdk-lib/aws-route53-targets";
import { SecurityStack } from "./stacks/SecurityStack";
const app = new App();
const appConfig: AppConfig = loadConfig(app);
const route53Stack = new Route53Stack(app, `ButlaiRoute53Stack-${appConfig.ENV}`, {
config: appConfig,
})
const certificateStack = new CertificateStack(app, `ButlaiCertificateStack-${appConfig.ENV}`, {
config: appConfig,
hostedZone: route53Stack.hostedZone
});
const networkStack = new NetworkStack(app, `ButlaiNetworkStack-${appConfig.ENV}`, {
config: appConfig
});
const securityStack = new SecurityStack(app, `ButlaiSecurityStack-${appConfig.ENV}`, {
vpc: networkStack.vpc,
});
const dataStack = new DataStack(app, `ButlaiDataStack-${appConfig.ENV}`, {
config: appConfig,
vpc: networkStack.vpc,
databaseSecurityGroup: securityStack.databaseSecurityGroup,
});
const lambdaStack = new LambdaStack(app, `ButlaiLambdaStack-${appConfig.ENV}`, {
config: appConfig,
vpc: networkStack.vpc,
databaseSecrets: dataStack.databaseSecrets,
lambdaSecurityGroup: securityStack.lambdaSecurityGroup,
databaseSecurityGroup: securityStack.databaseSecurityGroup,
});
const apiGatewayStack = new ApiGatewayStack(app, `ButlaiApiGatewayStack-${appConfig.ENV}`, {
config: appConfig,
hostedZone: route53Stack.hostedZone,
certificate: certificateStack.certificate,
testLambda: lambdaStack.testLambdaFunction,
createPost: lambdaStack.createPostLambdaFunction,
getPost: lambdaStack.getPostLambdaFunction,
});
```
And this is what I try to do:
```typescript
// postResourcesV1.addMethod("DELETE", props.testLambda);
```
this results in the following error in the Console:
The CloudFormation Console for this stack tells me this:
**Export ButlaiLambdaStack-dev:ExportsOutputFnGetAtttestFunctionFOOBAR cannot be deleted as it is in use by ButlaiApiGatewayStack-dev**
But there aren't any other references to that testLambda function elsewhere in my codebase. Next to that, I'm not trying to DELETE the whole Lambda function, I want to deploy a new version of the API without that Method.
### Expected Behavior
In the next deployment (that I'm trying to deploy), the method that I want to delete from the API Gateway should be removed.
The Lambda function itself will still exist in AWS, in case we want to revert to an older deployment version.
### Current Behavior
The current behaviour is a ROLLBACK.
Nothing else happens, the stack won't be updated, the method still exists and is callable.
### Reproduction Steps
If you would copy and paste the code that I posted above (the ApiGatewayStack). And deploy it using:
`cdk deploy --all`
Then, comment out one of the added Lambda Functions an re-run:
`cdk deploy --all`
### Possible Solution
_No response_
### Additional Information/Context
_No response_
### CDK CLI Version
2.147.0 (build 3338fc0)
### Framework Version
_No response_
### Node.js Version
v22.2.0
### OS
Mac OS 14.5 (23F79)
### Language
TypeScript
### Language Version
TypeScript (5.4.3)
### Other information
_No response_
Contributor guide
Research direction
Start with the ApiGatewayStack and Launcher.ts examples, then reproduce the behavior with cdk deploy --all after commenting out postResourcesV1.addMethod("DELETE", props.testLambda). Done means the API Gateway method is removed on deployment while the Lambda function remains available and the stacks do not roll back.
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