AWS SAM:为何无法为嵌套栈的HTTP API绑定自定义域名
解决方案
根因分析
两次部署失败的核心原因都是重复创建同一自定义域名资源:AWS中同一个自定义域名在同一区域全局唯一,不能在多个CloudFormation栈中重复声明创建。你在根栈已经完成了域名创建、证书绑定、Route53解析配置的操作,嵌套栈只需要完成路径映射即可,不需要再操作域名相关资源。
正确配置步骤
第一步:调整根栈配置,新增输出参数
根栈保持现有域名创建逻辑不变,在模板末尾新增输出参数,将域名信息、API默认部署阶段传递给嵌套栈:
# 根栈模板末尾新增Outputs部分 Outputs: ApiDomainName: Value: !Ref DomainName ApiDefaultStage: Value: !Ref AuthGatewayHttpApi.Stage
同时调整根栈中嵌套栈的引用配置,把输出的参数传递给嵌套栈:
NestedStackTwo: DependsOn: AuthGatewayHttpApi Type: AWS::CloudFormation::Stack Properties: TemplateURL: nested_stack.yaml Parameters: FirebaseProjectId: !Ref FirebaseProjectId DomainName: !Ref DomainName ApiStage: !Ref AuthGatewayHttpApi.Stage
第二步:调整嵌套栈配置,删除重复域名创建逻辑
嵌套栈删除所有AWS::ApiGatewayV2::DomainName相关的配置,仅保留API定义和路径映射配置即可,完整示例如下:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > aws-restapi Sample SAM Template for aws-restapi Globals: Function: Timeout: 5 VpcConfig: SecurityGroupIds: - sg-xxxxxx SubnetIds: - subnet-xxxxx Parameters: FirebaseProjectId: Type: String DomainName: Type: String ApiStage: Type: String Resources: # 嵌套栈独立的HTTP API定义 AuthGatewayHttpApi2: Type: AWS::Serverless::HttpApi Properties: Auth: Authorizers: FirebaseAuthorizer: IdentitySource: $request.header.Authorization JwtConfiguration: audience: - !Ref FirebaseProjectId issuer: !Sub https://securetoken.google.com/${FirebaseProjectId} DefaultAuthorizer: FirebaseAuthorizer # 仅做路径映射,关联根栈已经创建好的自定义域名 NestedApiMapping: Type: 'AWS::ApiGatewayV2::ApiMapping' Properties: DomainName: !Ref DomainName ApiId: !Ref AuthGatewayHttpApi2 Stage: !Ref ApiStage # 这里设置嵌套栈的统一路径前缀,对应你要求的/nested BasePath: nested # 业务函数配置保持不变 GetAllPromotionsFunction: Type: AWS::Serverless::Function Properties: CodeUri: aws-restapi/ Handler: source/promotions/promotions-getall.getAllPromotions Runtime: nodejs14.x Events: GetAllPromotionsAPIEvent: Type: HttpApi Properties: Path: /promotions/getall Method: get ApiId: !Ref AuthGatewayHttpApi2
最终效果
部署完成后即可符合你要求的访问规则:
- 根栈服务访问地址:
api.example.com/hello - 嵌套栈服务访问地址:
api.example.com/nested/promotions/getall
内容的提问来源于stack exchange,提问作者PeakGen
相关产品推荐
相关产品推荐

