如何使用AWS SAM部署到指定阶段且不影响其他阶段
问题原因
当前配置中把StageName作为AWS::Serverless::Api的固定属性,CloudFormation会将这个资源下的阶段配置和模板内容保持完全对齐。当你把属性值从Dev改成Prod时,CloudFormation会判定原有Dev阶段属于被移除的配置,部署时会自动删除,本质是把多阶段的生命周期绑定在了同一个API资源的单次部署配置上,自然会产生互相影响。
可行方案
根据需要的隔离程度选择对应实现方式即可:
方案1:共用API实例,阶段独立管理
适合需要共用API基础配置、仅做阶段隔离的场景。核心思路是关闭SAM自动创建默认阶段的能力,把每个阶段拆成独立资源管理,更新部署时可以按需把新版本绑定到指定阶段,不会触碰其他阶段的配置。
参考配置如下:
Resources: ApiGatewayApi: Type: AWS::Serverless::Api Properties: EndpointConfiguration: REGIONAL OpenApiVersion: "3.0" Name: asaf_api_second Description: "my api from sam" # 关闭SAM自动创建默认阶段、自动绑定部署的逻辑 StageName: !Ref AWS::NoValue Deploy: false # 每次API配置变更时,更新Deployment的逻辑ID或加时间戳/版本号参数触发重新创建 ApiDeployment: Type: AWS::ApiGateway::Deployment Properties: RestApiId: !Ref ApiGatewayApi Description: "API deployment for version tracking" # 独立的Dev阶段资源 DevStage: Type: AWS::ApiGateway::Stage Properties: RestApiId: !Ref ApiGatewayApi StageName: Dev DeploymentId: !Ref ApiDeployment # 单独配置Dev阶段的日志、限流、变量等规则 MethodSettings: - ResourcePath: "/*" HttpMethod: "*" LoggingLevel: INFO # 独立的Prod阶段资源 ProdStage: Type: AWS::ApiGateway::Stage Properties: RestApiId: !Ref ApiGatewayApi StageName: Prod # 验证Dev阶段运行正常后,再把Prod的DeploymentId指向新版本即可 DeploymentId: !Ref ApiDeployment MethodSettings: - ResourcePath: "/*" HttpMethod: "*" LoggingLevel: ERROR ThrottlingBurstLimit: 200
注意:新的ApiDeployment创建后不会自动切流到Prod,你可以手动更新Prod阶段绑定的DeploymentId完成发布,整个过程Dev阶段的流量、配置完全不受影响。
方案2:按阶段拆分独立CloudFormation栈
适合需要dev/prod环境完全隔离的场景,两个阶段的资源完全独立,从根本上避免互相影响。
实现步骤:
- 给SAM模板增加阶段参数,API名称带上阶段标识避免重名:
Parameters: DeploymentStage: Type: String AllowedValues: [Dev, Prod] Default: Dev Resources: ApiGatewayApi: Type: AWS::Serverless::Api Properties: EndpointConfiguration: REGIONAL StageName: !Ref DeploymentStage OpenApiVersion: "3.0" Name: !Sub "asaf_api_second_${DeploymentStage}" Description: "my api from sam"
- 部署不同阶段时使用独立的栈名,传入对应的阶段参数:
- 部署Dev环境:
sam deploy --stack-name asaf-api-dev --parameter-overrides DeploymentStage=Dev - 部署Prod环境:
sam deploy --stack-name asaf-api-prod --parameter-overrides DeploymentStage=Prod
这种模式下两个阶段对应完全独立的API Gateway实例、独立的CloudFormation栈,任意一个栈的更新、删除操作都不会对另一个阶段产生任何影响。
避坑提醒:不要在同一个栈里直接修改
AWS::Serverless::Api的StageName属性重复部署,按照CloudFormation的资源更新逻辑,旧阶段必然会被判定为废弃资源删除。
内容的提问来源于stack exchange,提问作者Asaf Shay
相关产品推荐
相关产品推荐

