Skip to content
New issue

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

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

Already on GitHub? # to your account

API Gateway & Lambda: Unable to delete Lambda function from AWS API Gateway (Lambda still in use by API Gateway) #30658

Open
tpotjj opened this issue Jun 25, 2024 · 2 comments
Labels
@aws-cdk/aws-lambda Related to AWS Lambda bug This issue is a bug. effort/medium Medium work item – several days of effort p3

Comments

@tpotjj
Copy link

tpotjj commented Jun 25, 2024

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:

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:

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:

// 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

@tpotjj tpotjj added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jun 25, 2024
@github-actions github-actions bot added the @aws-cdk/aws-lambda Related to AWS Lambda label Jun 25, 2024
@pahud pahud self-assigned this Jun 25, 2024
@pahud
Copy link
Contributor

pahud commented Jun 25, 2024

Export ButlaiLambdaStack-dev:ExportsOutputFnGetAtttestFunctionFOOBAR cannot be deleted as it is in use by ButlaiApiGatewayStack-dev

This error indicates the export ExportsOutputFnGetAtttestFunctionFOOBAR from ButlaiLambdaStack-dev is currently in used by ButlaiApiGatewayStack-dev stack and cloudformation was trying to "unexport" it, which is rejected, hence rollback.

If you just update this. Can you run npx cdk diff and see what's going to be changed? As I didn't see how you pass those props, my guess is props.testLambda might from cross stack reference, which auto built the output exports but I am not sure.

// postResourcesV1.addMethod("DELETE", props.testLambda);

@pahud pahud added the p3 label Jun 25, 2024
@pahud pahud removed their assignment Jun 25, 2024
@pahud pahud added effort/medium Medium work item – several days of effort response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed needs-triage This issue or PR still needs to be triaged. labels Jun 25, 2024
@tpotjj
Copy link
Author

tpotjj commented Jun 27, 2024

@pahud Thanks for the response.

I've updated my question so that it contains the Launcher.ts file as well.
As you can see, there is no cross-stack-reference between the ButlaiApiGatewayStack-dev and the ButlaiLambdaStack-dev.
The only thing which I do, is passing the Lambda functions created in the Lambda stack to the ApiGateway stack.

I also ran npx cdk diff, the results are below.
Screenshot 2024-06-27 at 10 18 30

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jun 27, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
@aws-cdk/aws-lambda Related to AWS Lambda bug This issue is a bug. effort/medium Medium work item – several days of effort p3
Projects
None yet
Development

No branches or pull requests

2 participants