【问题标题】:AWS API Gateway HttpAPI SAM Custom Domain Name ErrorAWS API Gateway HttpAPI SAM 自定义域名错误
【发布时间】:2021-08-05 15:50:03
【问题描述】:

我想将现有的 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 Gateway 中配置了现有的自定义域。看起来它试图创建一个自定义域名,有没有办法将 HTTP API 实例映射到现有的自定义域?对于 REST API,我使用 AWS::ApiGateway::BasePathMapping 来映射此任务,但找不到 HTTP API 替代方案。

【问题讨论】:

  • 你试过AWS::ApiGatewayV2::ApiMapping吗? docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
  • 感谢@acm 的评论,是的,我确实检查了 ApiMapping 文档,但看不到它的基本路径映射配置,它只有域名配置。在我当前的实现中,我有几个 api(公司 api、用户 api、分析 api 等)使用相同的域名但具有不同的基本路径映射,因此当通过 www.my-api.com/company-api 收到请求时/companies 它命中公司 api 网关实例,你知道我如何使用 ApiMapping 实现相同的结果吗?
  • 您使用 ApiMappingKey 来表示:docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…。实际上,这就是 SAM 为 BasePath 所做的事情。您可以尝试看看它是否按您的预期工作吗?
  • @acm 谢谢,这对我有用!将您的评论作为答案,我会接受它:)
  • 很高兴听到它有帮助,将其添加为下面的答案。

标签: amazon-web-services aws-lambda aws-api-gateway aws-sam aws-http-api


【解决方案1】:

您可以使用AWS::ApiGatewayV2::ApiMapping。它允许您将现有的自定义域名链接到AWS::Serverless::HttpApi。您可以将 ApiMappingKey 用于不同的路径映射 (BasePath),因为这就是 SAM 所做的 under the hood。

【讨论】:

【解决方案2】:

我认为没有办法做到这一点,因为这是来自 API Gateway 的旧 REST API 和新的 HTTP API 之间的一个相当彻底的(内部)变化。

在旧的 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

【讨论】:

  • 感谢回复,此时宕机不是问题,我只想从Rest API转到Http API。如果您可以指向一些 aws sam 示例文档如何在具有不同基本路径映射的单个自定义域名下配置多个 api 网关实例,这将非常有帮助。在我当前的 API 中,我有多个嵌套的 cfn 堆栈,它们正在创建自己的 API 网关实例,使用 AWS::ApiGateway::BasePathMapping 我将每个 API 网关实例映射到具有唯一基本路径的相同自定义域名:1. api.com /company-api/x - 公司 api gw 2. api.com/user-api/x - 用户 api
  • @Obj3ct 我已经编辑了答案并添加了一个我遇到的用于 Rest API 和更新的 HTTP API 的自定义域名的示例。希望对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 2020-10-04
  • 2018-05-29
  • 1970-01-01
  • 1970-01-01
  • 2018-12-26
  • 2021-03-22
  • 2020-09-16
  • 2021-06-17
相关资源
最近更新 更多