如何获取 CloudFront 分配的域名



目标是为我的无服务器 API 创建自定义域:api.example.com. 所以我的方法是创建这个 Route53 记录:

ApiDomainRecord:
Type: AWS::Route53::RecordSet
Properties:
Type: A
Name: api.example.com
HostedZoneId: Z2PERRPAZRTJGB
AliasTarget:
HostedZoneId: Z2FDTNDATAQYW2
DNSName:
Fn::GetAtt: [ --> what do we enter here <--, DomainName ]

但是,如何提供无服务器发出的 CloudFront 中的域名呢?

获取 API 网关网址

我发现在无服务器模板中获取 API 网关 URL 的唯一方法是自己将其拼凑在一起。 我当然不是第一个这样做的人。

无服务器创建的 API 称为ApiGatewayRestApi。 由于模板知道区域和阶段,因此可以像这样拼凑 URL:

DNSName:
Fn::Join:
- ""
- - "https://"
- Ref: ApiGatewayRestApi
- ".execute-api.${self:provider.region}.amazonaws.com/${self:provider.stage}"

不幸的是,这行不通

尽管我相信 API Gateway 在后台使用 CloudFront(至少对于边缘优化的终端节点),但将上述代码插入脚本将导致错误,抱怨托管区域对此 URL 有误。 这并不奇怪,因为...execute-api...amazonaws.com显然不是cloudfront.net的子域。

我认为您必须使用 API 网关的自定义域功能来实现这一目标。 创建 CloudFront 时,您将获得一个真实的 CloudFront URL,您可以将其与 CloudFront 托管区域 (Z2FDTNDATAQYW2) 一起使用。

这样做的缺点是,您可以获得为您的 API 创建的 CloudFront 分配。 这意味着部署一个全新的 API 将需要 ~20-30 分钟,而不仅仅是一两分钟。


没有插件

在您的无服务器模板中,这意味着除了 Route 53RecordSet之外,还要创建一个 API 网关DomainName(可能还有一个BasePathMapping):

resources:
Resources:
ApiDomainRecord:
Type: AWS::ApiGateway::DomainName
Properties:
CertificateArn: arn:aws:acm:us-east-1:<AWS_ACCOUNT>:certificate/3XXXXXXX-2XXX-4XXX-8XXX-8XXXXXXXXXXX
DomainName: api.example.com
ApiDomainMapping:
Type: AWS::ApiGateway::BasePathMapping
Properties:
BasePath: r53
DomainName: api.example.com
RestApiId:
Ref: ApiGatewayRestApi
ApiDNSRecord:
Type: AWS::Route53::RecordSet
Properties:
Type: A
Name: api.example.com
HostedZoneId: ZXXXXXXXXXXXXXA
AliasTarget:
HostedZoneId: Z2FDTNDATAQYW2
DNSName:
Fn::GetAtt: [ApiDomainRecord, DistributionDomainName]

在这个例子中,我在api.example.com/r53/<STAGE>/<API_RESOURCE>处点击了我的 API。 我的证书是*.example.com的。 您还可以在 BasePathMap 中指定阶段(如果不希望在 URL 中指定阶段)。


使用插件

这是一个相当多的样板文件,我讨厌将 ARN 硬编码到我的模板(在本例中为证书)中。

serverless-domain-manager插件(推荐在这里)可以减少麻烦。 它不仅可以减少您编写的样板数量,还允许您指定证书名称,而不是 ARN。 我第一次尝试时就可以轻松使其工作。

使用此插件,上面的 CloudFormation 可以在模板的custom部分中替换为一小节:

custom:
customDomain:
domainName: api.example.com
basePath: r53
certificateName: "*.example.com"
createRoute53Record: true

最新更新