将 AWS::Route53::RecordSet DnsRecord 添加到无服务器 Cloudfront 分发

Add AWS::Route53::RecordSet DnsRecord to a serverless Cloudfront Distribution

我在 serverless.yml 文件中找到 this 如何将 route53 dns 记录与 S3 存储桶相关联。

我已尝试使它适应部署云端分发包的情况

DnsRecord:
  Type: "AWS::Route53::RecordSet"
  Properties:
    AliasTarget:
      DNSName: <cloudfrontdistribution id>
      HostedZoneId: Z21DNDUVLTQW6Q
    HostedZoneName: ${self:custom.appFQDN}.
    Name:
      Ref: WebAppCloudFrontDistribution
    Type: 'CNAME'

但我正在努力解决如何将分发 ID 作为引用而不是固定字符串的问题。

我该怎么做?

要设置 AliasTarget,实际上您只需要为 DNSName 参数提供 CloudFront DNS 名称,而不是分配 ID。你可以这样做:

!GetAtt WebAppCloudFrontDistribution.DomainName

我假设 WebAppCloudFrontDistribution 是模板中 AWS::CloudFront::Distribution 资源的逻辑 ID,而不是参数。如果这实际上是一个参数,只需将参数的值设置为在 CloudFront 的 AWS 控制台控制面板中为分配列出的 DNS 名称。

您还需要在模板中修复一些其他问题:

  • HostedZoneName 应该是 Route53 托管区域的名称,而不是您要使用的 FQDN。就个人而言,我更喜欢将 HostedZoneId 属性 用于 AWS::Route53::RecordSet 资源,因为它更清楚这个 属性 的含义,但对每个资源来说都是如此。 (注意:AWS::Route53::RecordSet 资源的 HostedZoneId 属性 应该是您的托管区域的 HostedZoneId,与 AliasTarget HostedZoneId 的值不同。)
  • 名称应该是您希望作为 CloudFront 分配资源 CNAME 的 DNS 名称。
  • 我知道这有点奇怪,但是对于别名目标,您必须将类型设置为 "A"(对于 IPv4)或 "AAAA"(IPv6)。我建议两者都做 - 您可以通过创建 AWS::Route53::RecordSet 资源的副本来做到这一点,但将类型设置为 "AAAA" 而不是 "A".

最后,请注意,为了使其正常工作,您还需要确保将 FQDN 添加为 CloudFront 分发资源的备用名称 - 您可以使用 "Aliases" 属性 分配资源的 "DistributionConfig" 属性,或者如果您没有在此模板中创建资源,则通过在 AWS 控制台中手动配置分配设置。

这是我在无服务器模板中的工作配置:

DnsRecord:
  Type: "AWS::Route53::RecordSet"
  Properties:
    AliasTarget:
      DNSName:
        Fn::GetAtt:
          - CloudFrontDistribution
          - DomainName
      # Looks like it is always the same for CloudFront distribs.
      # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html
      # https://docs.aws.amazon.com/general/latest/gr/rande.html#cf_region
      HostedZoneId: ${self:custom.zoneId}
    HostedZoneName: ${self:custom.secondLevelDomain}.
    Name: ${self:custom.appFQDN}
    Type: 'A'

CloudFrontDistribution:
  Type: AWS::CloudFront::Distribution
  Properties:
    DistributionConfig:
      ...
      Aliases:
        - ${self:custom.appFQDN}

同样由 Tom McLaughlin 提供的示例提供: https://github.com/ServerlessOpsIO/serverless-zombo.com/blob/master/serverless.yml

我努力创建一个 AWS::Route53::RecordSet 的 CloudFormation,生成类型为 "The resource failed to create" 的不具体、无用的错误消息。对我来说关键是使用 HostedZoneId 而不是 HostedZoneName 来指定父 "hosted zone"。这就是我最终得到的:

  NaaaaaComDNSEntry: 
    Type: 'AWS::Route53::RecordSet'
    DependsOn: NaaaaaComCloudFront
    Properties: 
      AliasTarget:
        DNSName: !GetAtt NaaaaaComCloudFront.DomainName
        # For CloudFront, HostedZoneId is always Z2FDTNDATAQYW2, see:
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html#cfn-route53-aliastarget-hostedzoneid
        HostedZoneId:  Z2FDTNDATAQYW2
    # HostedZoneId is for ID for 'naaaaa.com.'; In theory its valid to use `HostedZoneName` OR `HostedZoneId`
    # but in practice the recordset always failed to create if I used `HostedZoneName`
    HostedZoneId: ZABCDEFGHIJK5M
    Name: 'www.naaaaa.com.'
    Type: 'A'