AWS API 网关 HttpAPI SAM 自定义域名错误

AWS API Gateway HttpAPI SAM Custom Domain Name Error

我想将我现有的 Rest API 移动到 HTTP API,但在自定义域配置中出现错误。我的 HTTP API 的 SAM 文件是:

  resHttpApiGateway:
    Type: AWS::Serverless::HttpApi
    Properties:
      StageName: !Sub "${paramEnvironment}"
      CorsConfiguration:
        AllowOrigins:
          - "*"
        AllowHeaders:
          - Content-Type
          - X-Amz-Date
          - Authorization
          - X-Api-Key
          - correlation-object
        AllowMethods:
          - GET
          - POST
          - PUT
          - DELETE
      Auth:
        Authorizers:
          authTokenAuthorizer:
            AuthorizerPayloadFormatVersion: 1.0
            FunctionArn: !Ref paramLambdaAuthorizer
            Identity:
              Headers:
                - Authorization
              ReauthorizeEvery: 0
      Domain:
        EndpointConfiguration: REGIONAL
        DomainName: !If
          - condIsLocal
          - !Sub "dev.${paramBaseDomain}"
          - !Sub "${paramEnvironment}.${paramBaseDomain}"
        CertificateArn: arn:aws:acm:xxx
        Route53:
          HostedZoneId: xxx
        BasePath: "company-api"

我在 Cloudformation 中遇到错误:

The domain name you provided already exists. (Service: AmazonApiGatewayV2; Status Code: 400; Error Code: BadRequestException; Request ID: ddba8c65-63de-4be4-9316-afd777e8b63f; Proxy: null)

因为我在 API 网关中配置了一个现有的自定义域。看起来它试图创建一个自定义域名,有没有办法将 HTTP API 实例映射到现有的自定义域?对于 REST API,我使用 AWS::ApiGateway::BasePathMapping 来映射此任务,但找不到 HTTP API 替代方法。

我认为没有办法做到这一点,因为这是 API 网关的旧 REST API 与较新的 HTTP [=23] 之间的(内部)相当彻底的变化=]s.

在旧的 REST API 中,自定义域名始终使用 CloudFront 分配进行配置(即使这在 CloudFront UI 中不可见)并且在 CloudFront 中,不可能关联更多而不是具有相同 CNAME 的一个发行版。如果我没记错的话,这甚至是真正的跨账户。

虽然我自己没有这方面的经验,但使用 wildcard domains 可能有一个解决方法。

根据 API 的位置 运行 以及 API 的 SLA 要求,简单地停机以确保此更改顺利进行可能更容易.在停机的情况下,不要忘记事先降低 Route53 DNS 条目的 TTL 值,这样您的新记录将更快地传播到所有 DNS 缓存。

(编辑) 事实证明这是可能的,只要您不使用 AWS SAM 创建映射。以下是来自 this source

的简短示例
[...]
Resources:
 [...]

  CustomDomainName: # Creates the domain name only
    Type: AWS::ApiGatewayV2::DomainName
    Properties: 
      DomainName: !Ref DomainName
      DomainNameConfigurations: 
        - EndpointType: REGIONAL
          CertificateArn: !If [CreateCert, !Ref GeneratedCert, !Ref CertArn]

  HttpApiMapping: # Create a mapping to an HTTP API (V2)
    Type: AWS::ApiGatewayV2::ApiMapping
    Properties: 
      ApiId: !Ref HttpApiGateway
      ApiMappingKey: http
      DomainName: !Ref CustomDomainName
      Stage: !Ref HttpApiGatewayApiGatewayDefaultStage ## = {LogicalName} + ApiGateway + {StageName} + Stage

  RestApiMapping: #Create a maooing to a REST API (V1)
    Type: AWS::ApiGatewayV2::ApiMapping
    Properties: 
      ApiId: !Ref RestApiGateway
      ApiMappingKey: rest
      DomainName: !Ref CustomDomainName
      Stage: !Ref RestApiGatewayProdStage ## = {Logicalname} + {StageName} + Stage

  HttpApiGateway: # Creates a HTTP API endpoint under the customm domian
    Type: AWS::Serverless::HttpApi

  RestApiGateway: # Creates a Rest API endpoint under the customm domian
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
  [...]

  RecordSet: # Creates a record set in the hosted zone for custom domain to point at the APICustomDomain alias
    Type: AWS::Route53::RecordSet
    Properties:
      Name: !Ref DomainName
      HostedZoneId: !If [CreateZone, !Ref GeneratedZone, !Ref ZoneId]
      AliasTarget: 
        DNSName: !GetAtt CustomDomainName.RegionalDomainName
        HostedZoneId: !GetAtt CustomDomainName.RegionalHostedZoneId
      Type: A

您可以使用 AWS::ApiGatewayV2::ApiMapping. It allows you to link an existing custom domain name to AWS::Serverless::HttpApi. You can use ApiMappingKey for your different path mappings (BasePath) as that's what SAM does under the hood.