【问题标题】:Custom Domain Name for WebSockets API with Serverless使用无服务器的 WebSockets API 的自定义域名
【发布时间】:2020-06-26 07:57:09
【问题描述】:

我正在使用无服务器管理应用程序的 REST API,并希望在同一区域使用 WebSockets API 扩展此设置。一切都应该使用相同的证书,但不同的子域来处理。

起初我使用sls create_domain --stage=... 创建了一个新的自定义域。 然后我尝试将它添加到新的 WebSockets 堆栈中,但以这个错误结束:

错误:找不到 CloudFormation 资源...

我在 Github 上发现 CloudFormation 现在似乎不支持这个,所以 Serverless 不支持它。

所以我尝试在 UI 中手动将我的舞台附加到自定义域名:

REST API 和 HTTP API 只能在同一个域名上混合使用 通过 API Gateway 的 V2 域名接口完成。现在, WebSocket API 只能附加到一个域名与其他 WebSocket API。这也必须通过 API Gateway 的 V2 域名接口。

出现更多混乱,因为在这种情况下它甚至不是同一个域名。新域名为sockets.<DOMAIN>.com,现有域名为api.<DOMAIN>.com。还是不同的子域属于“同一个域名”?

尽管如此,我还是尝试通过 apigatewayv2 CLI 再次创建自定义域:

aws apigatewayv2 create-domain-name --domain-name <DOMAIN> --domain-name-configurations file://domain-configuration.json --region eu-west-1

域配置.json:

[
{
    "ApiGatewayDomainName": "<DOMAIN>",
    "CertificateArn": "arn:aws:acm:us-east-1:<ACCOUNT_ID>:certificate/<CERT_ID>",
    "CertificateName": "<DOMAIN>",
    "DomainNameStatus": "AVAILABLE",
    "EndpointType": "EDGE",
    "SecurityPolicy": "TLS_1_2"
}

]

但这会导致以下错误:

调用 CreateDomainName 操作时发生错误 (BadRequestException):证书 ARN 无效:arn:aws:acm:us-east-1:924441585974:certificate/b88f0a3f-1393-4a16-a876-9830852b5207。证书必须在“eu-west-1”中。

我目前的状态是 API Gateway 只允许自定义证书位于 us-east-1,所以这个错误让我更加困惑。

总结:我完全不知道如何将自定义域名附加到我的 WebSocket API 阶段。我很高兴看到正确方向的每一个提示!

【问题讨论】:

    标签: amazon-web-services websocket aws-api-gateway serverless-framework


    【解决方案1】:

    找到使用自定义 CloudFormation 资源模板的解决方案:

    resources:
      Resources:
        WebSocketDomainName:
          Type: AWS::ApiGatewayV2::DomainName
          Properties:
            DomainName: <domain-name>
            DomainNameConfigurations:
              - EndpointType: 'REGIONAL'
                CertificateArn: <cert-arn>
        WebSocketMapping:
          Type: AWS::ApiGatewayV2::ApiMapping
          Properties:
            ApiId: <api-id>
            DomainName: !Ref WebSocketDomainName
            Stage: <stage-name>
        DNSRecord:
          Type: AWS::Route53::RecordSet
          Properties:
            HostedZoneName: <hosted-zone-name>.
            TTL: '900'
            ResourceRecords:
              - !GetAtt [ WebSocketDomainName, RegionalDomainName ]
            Name: <domain-name>
            Type: CNAME
    

    编辑:现在使用serverless-domain-manager! ?

    custom:
      customDomain:
        rest:
          domainName: rest.serverless.foo.com
          stage: ci
          basePath: api
          certificateName: '*.foo.com'
          createRoute53Record: true
          endpointType: 'regional'
          securityPolicy: tls_1_2
        http:
          domainName: http.serverless.foo.com
          stage: ci
          basePath: api
          certificateName: '*.foo.com'
          createRoute53Record: true
          endpointType: 'regional'
          securityPolicy: tls_1_2
        websocket:
          domainName: ws.serverless.foo.com
          stage: ci
          basePath: api
          certificateName: '*.foo.com'
          createRoute53Record: true
          endpointType: 'regional'
          securityPolicy: tls_1_2
    

    【讨论】:

    • 只使用前两个资源和 Cloudflare 为我工作
    • “发生错误:WebSocketMapping - 目前,WebSocket API 不能与同一域名上的 REST API 或 HTTP API 混合使用。(服务:AmazonApiGatewayV2;”对于 v2,WebSocket 与 HTTP 的映射已被弃用。 .?
    • @JasonMullings 你找到解决方案了吗?
    • @MFAL 抱歉,这里没有解决方案,AWS 不允许。我建议不要将 SLS 作为 Websocket 解决方案,因为每次调用的成本非常高。坚持使用 EC2 实例...
    【解决方案2】:

    感谢@tpschmidt 的帮助! 只需添加,如果您想要为您的 websocket 域提供 BasePathMapping,请将 ApiMappingKey 添加到上面提供的 Cloudformation。例如:

    WebSocketMapping:
          Type: AWS::ApiGatewayV2::ApiMapping
          Properties:
            ApiId: <api-id>
            DomainName: !Ref WebSocketDomainName
            Stage: <stage-name>
            ApiMappingKey: <stage-name> #(e.g. prod)
    

    【讨论】:

      【解决方案3】:

      我必须进行一些小调整才能在私有 VPC 中使用 Lambda,并支持 WebSockets 和自定义域。

      1. CertificateArn 必须来自 ACM,并且不能是上传到 IAM 的证书。
      2. 我使用 A 记录而不是 CNAME
      WebSocketDomainName:
          Type: AWS::ApiGatewayV2::DomainName
          Properties:
              DomainName: !Ref DomainName
              DomainNameConfigurations:
                  - EndpointType: REGIONAL
                    CertificateArn: <your-certificate-arn>
      
      # This maps /staging or /prod to just the domain name
      WebSocketMapping:
          Type: AWS::ApiGatewayV2::ApiMapping
          Properties:
              ApiId: <your-api-id>
              DomainName: !Ref WebSocketDomainName
              Stage: <your-stage>
      
      Route53DNS:
          Type: AWS::Route53::RecordSetGroup
          Properties:
              HostedZoneName: !Ref Route53HostedZone
              RecordSets:
                  - Name: !Ref DomainName
                    Type: A
                    AliasTarget:
                        HostedZoneId: ZLY8HYME6SFDD # This means eu-west-1 ApiGateWay
                        DNSName:
                            !GetAtt [WebSocketDomainName, RegionalDomainName]
      

      对于您的HostedZoneId 检查:https://docs.aws.amazon.com/general/latest/gr/apigateway.html

      【讨论】:

        猜你喜欢
        • 2018-11-27
        • 1970-01-01
        • 2019-09-29
        • 2018-02-24
        • 2014-08-22
        • 1970-01-01
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多