卓:为什么我无法将自定义域分配给嵌套堆栈?

AWS: Why I am unable to assign a custom domain to the nested stack?

我正在尝试将自定义域集成到我正在使用 AWS API GatewayAWS Lambda 开发的 HTTP API。我正在使用 AWS SAM 模板。我有一个根堆栈和嵌套堆栈。

对于这个问题,我将使用带有一个嵌套堆栈的代码片段。在那里,这就是我希望 URL 端点成为

的方式
  1. 根堆栈 - api.example.com
  2. 嵌套堆栈 - api.example.com/nested

下面是我的代码

根堆栈

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  aws-restapi

  Sample SAM Template for aws-restapi
  
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 5
    VpcConfig:
        SecurityGroupIds:
          - sg-041f24xxxx921e8e
        SubnetIds:
          - subnet-0xxxxx2d


Parameters:
  FirebaseProjectId:
    Type: String
  
  #Dont create this domain in the AWS Console manually, so it will fail here
  DomainName:
    Type: String
    Default: api.example.com

Resources:
  AuthGatewayHttpApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      Domain:
        DomainName: !Ref DomainName
        EndpointConfiguration: REGIONAL
        CertificateArn: arn:aws:acm:us-east-1:xxxx:certificate/xxxx-420d-xxxx-b40d-xxxx
        Route53:
          HostedZoneId: xxxxxxxxxxx
      Auth:
        Authorizers:
          FirebaseAuthorizer:
            IdentitySource: $request.header.Authorization
            JwtConfiguration:
              audience:
                - !Ref FirebaseProjectId
              issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
        DefaultAuthorizer: FirebaseAuthorizer

 
  AuthFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: aws-restapi/
      Handler: source/testfile.lambdaHandler
      Runtime: nodejs14.x
      Events:
        Gateway:
          Type: HttpApi
          Properties:
            ApiId: !Ref AuthGatewayHttpApi
            Path: /hello
            Method: get

  NestedStackTwo:
    DependsOn: AuthGatewayHttpApi
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: nested_stack.yaml
      Parameters:
        FirebaseProjectId: !Ref FirebaseProjectId
        DomainName: !Ref DomainName

嵌套堆栈

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-xxxxxxxxxxxx
        SubnetIds:
          - subnet-xxxxxxxxxxx

Parameters:
  FirebaseProjectId:
    Type: String
  
  DomainName:
    Type: String

Resources:

  AuthGatewayHttpApi2:
    Type: AWS::Serverless::HttpApi
    Properties:
      Domain:
        DomainName: !Ref DomainName
        BasePath: two
        EndpointConfiguration: REGIONAL
        CertificateArn: arn:aws:acm:us-east-1:xxxxx:certificate/xxxxx-xxxx-xxxx-xxxx-xxxx
        Route53:
          HostedZoneId: xxxxxxxxxxxxx
      Auth:
        Authorizers:
          FirebaseAuthorizer:
            IdentitySource: $request.header.Authorization
            JwtConfiguration:
              audience:
                - !Ref FirebaseProjectId
              issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
        DefaultAuthorizer: FirebaseAuthorizer

  GetAllPromotionsFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: aws-restapi/
      Handler: source/promotions/promotions-getall.getAllPromotions
      Runtime: nodejs14.x
      Events:
        GetAllPromotionsAPIEvent:
          Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /promotions/getall
            Method: get
            ApiId: !Ref AuthGatewayHttpApi2
  

但是我无法让它工作,因为嵌套堆栈无法创建。下面是错误

CREATE_FAILED                      AWS::CloudFormation::Stack         NestedStackTwo
                                                    

Embedded stack arn:aws:cloudformation:us-east-1 xxxxx:stack/aws-restapi-NestedStackTwo-8KBISZRAVYBX/a3fcc010-0ce4-11ec-9c90-0e8a861a6983 was not successfully created:

 The following resource(s) failed to create: [ApiGatewayDomainNameV234ac706a57] 

我相信这是因为根堆栈创建了域,而嵌套堆栈正在尝试重新创建它而不是重复使用它。

但是,有趣的是;如果我使用 AWS API GATEWAY Web 控制台,我可以立即完成此操作。

我怎样才能让它在 aws-sam 中工作?

更新

根据用户 LRutten 的建议,我为嵌套堆栈想出了以下代码。

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

Resources:

  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
  
  MyApiMapping:
    Type: 'AWS::ApiGatewayV2::ApiMapping'
    Properties:
      DomainName: !Ref DomainName
      ApiId: !Ref AuthGatewayHttpApi2
      Stage: prod
  
  MyDomainName:
    Type: 'AWS::ApiGatewayV2::DomainName'
    Properties:
      DomainName: !Ref DomainName
      DomainNameConfigurations:
        - EndpointType: REGIONAL
          CertificateArn: arn:aws:acm:us-east-1:716460586643:certificate/bac44716-420d-431b-b40d-01378f20432d


  GetAllPromotionsFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: aws-restapi/
      Handler: source/promotions/promotions-getall.getAllPromotions
      Runtime: nodejs14.x
      Events:
        GetAllPromotionsAPIEvent:
          Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /promotions/getall
            Method: get
            ApiId: !Ref AuthGatewayHttpApi2

最后出现以下错误

Embedded stack arn:aws:cloudformation:us-east-1:716460586643:stack/aws-restapi-NestedStackTwo-14SAYLRO1WD1D/62336020-xx-xx-a04e-x was not successfully created:

The following resource(s) failed to create: [MyDomainName, MyApiMapping]. 

事实上,当您在此处指定域名称时,SAM 总是会创建该域。它也在文档中说明。

要解决这个问题,您可以省略 AWS::Serverless::HttpApi 资源中的整个域配置,并自己编写 SAM 创建的资源。所以添加一个带有

的部分
Type: AWS::ApiGatewayV2::ApiMapping
Properties: 
  ApiId: String
  ApiMappingKey: String
  DomainName: String
  Stage: String

Docs

确保 ApiMapping 中的 Stage 属性 也出现在 API 的 StageName 属性 中。

还有一个

Type: AWS::ApiGatewayV2::DomainName
Properties: 
  DomainName: String
  DomainNameConfigurations: 
    - DomainNameConfiguration
  MutualTlsAuthentication: 
    MutualTlsAuthentication
  Tags: Json

Docs

无需两次定义域本身就可以手动添加它们。

编辑:woops 并没有真正思考清楚。你当然应该只有映射,而不是域名本身:P.