You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法从AWS API Gateway移除Lambda函数:提示仍被引用

问题:移除API Gateway中Lambda方法时CloudFormation报错

问题描述

被这个问题卡了好几天,想从AWS API Gateway里移除一个Lambda函数的关联方法,但不想删除整个Lambda函数(实际上也无法删除)。怀疑问题出在旧部署版本还在引用该Lambda——因为设置了retainDeployments: true?

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);
    }
}

现在想要删除最后一个方法:

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

但部署时CloudFormation控制台报错:

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

代码库中没有其他地方引用这个testLambda函数,只是想部署不含该方法的API新版本,请问遗漏了什么?该如何解决?

更新1:Launcher.ts代码

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
});
certificateStack.addDependency(route53Stack);

const networkStack = new NetworkStack(app, `ButlaiNetworkStack-${appConfig.ENV}`, {
    config: appConfig
});

const securityStack = new SecurityStack(app, `ButlaiSecurityStack-${appConfig.ENV}`, {
    vpc: networkStack.vpc,
});
securityStack.addDependency(networkStack);

const dataStack = new DataStack(app, `ButlaiDataStack-${appConfig.ENV}`, {
    config: appConfig,
    vpc: networkStack.vpc,
    databaseSecurityGroup: securityStack.databaseSecurityGroup,
});
dataStack.addDependency(securityStack);

const lambdaStack = new LambdaStack(app, `ButlaiLambdaStack-${appConfig.ENV}`, {
    config: appConfig,
    vpc: networkStack.vpc,
    databaseSecrets: dataStack.databaseSecrets,
    lambdaSecurityGroup: securityStack.lambdaSecurityGroup,
    databaseSecurityGroup: securityStack.databaseSecurityGroup,
});
lambdaStack.addDependency(dataStack);

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,
});
apiGatewayStack.addDependency(route53Stack);
apiGatewayStack.addDependency(certificateStack);
apiGatewayStack.addDependency(lambdaStack);

解决方案

1. 移除不必要的Lambda参数传递

报错的核心原因是:尽管你注释了API方法,但ApiGatewayStack的Props定义中仍保留testLambda参数,且Launcher.ts里还在传递该Lambda实例。CDK会自动为跨栈传递的资源创建CloudFormation导出/导入依赖,导致CloudFormation认为该Lambda的导出仍被ApiGatewayStack使用。

解决步骤:

  • 修改ApiGatewayProps,移除testLambda字段:
    interface ApiGatewayProps extends StackPropsConfig {
        hostedZone: IHostedZone;
        certificate: ICertificate;
        createPost: LambdaIntegration;
        getPost: LambdaIntegration;
    }
    
  • 修改Launcher.ts中ApiGatewayStack的实例化代码,删除testLambda参数:
    const apiGatewayStack = new ApiGatewayStack(app, `ButlaiApiGatewayStack-${appConfig.ENV}`, {
        config: appConfig,
        hostedZone: route53Stack.hostedZone,
        certificate: certificateStack.certificate,
        createPost: lambdaStack.createPostLambdaFunction,
        getPost: lambdaStack.getPostLambdaFunction,
    });
    

2. 分阶段部署(若直接修改后仍报错)

如果一次性修改后部署失败,可分两步执行:

  1. 先保留testLambda参数和传递,但注释掉API方法,部署一次。此时API会更新为不含DELETE方法的版本,但仍保留跨栈依赖。
  2. 再移除testLambda参数和传递,再次部署,此时CloudFormation会清理掉ApiGatewayStack对该Lambda的导入依赖,报错消失。

3. 清理旧API部署(可选)

由于设置了retainDeployments: true,旧的API部署版本会保留在AWS控制台中。这些旧部署可能仍持有对Lambda的执行权限,虽然不影响当前部署,但可以手动删除不再使用的部署版本,避免后续混淆。

4. 检查Lambda权限

确认API Gateway对该testLambda的执行权限是否已被CDK自动清理。若存在手动添加的权限,需手动删除IAM中对应的权限策略。


内容的提问来源于stack exchange,提问作者tpotjj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 23:16:03