在現有 API Gateway 中加入自訂網域時,需要注意 Endpoint type,有分 Regional 、edge-optimized、private 三種,以 public endpoint 來說,有 Regional 、edge-optimized 兩種,在加入自訂網域時,必定需要 SSL 憑證 (AWS 稱為 ACM),在新增 ACM 需要注意 Region 的問題
假設如果 API Gateway 的 Endpoint type 是 Regional, CloudFormation 的設定如下
AWSTemplateFormatVersion: "2010-09-09"
Description: "Setup API Gateway custom domain name"
Parameters:
AcmArn:
Type: String
CustomDomainName:
Type: String
ApiID:
Type: String
DomainHostZoneId:
Type: String
Resources:
ApiGatewayCustomDomainName:
Type: "AWS::ApiGateway::DomainName"
Properties:
CertificateArn: !Ref AcmArn
DomainName: !Ref CustomDomainName
BasePathMapping:
Type: "AWS::ApiGateway::BasePathMapping"
DependsOn: ApiGatewayCustomDomainName
Properties:
DomainName: !Ref CustomDomainName
RestApiId: !Ref ApiID
Stage: dev
CustomDomainRecord:
Type: "AWS::Route53::RecordSet"
DependsOn: ApiGatewayCustomDomainName
Properties:
Name: !Ref CustomDomainName
Type: A
HostedZoneId: !Ref DomainHostZoneId
AliasTarget:
DNSName: !GetAtt ApiGatewayCustomDomainName.DistributionDomainName
HostedZoneId: !GetAtt ApiGatewayCustomDomainName.DistributionHostedZoneId
CloudFormation 錯誤訊息
Invalid request provided: Invalid certificate ARN: arn:aws:acm:ap-northeast-1:093611479171:certificate/edd8180c-8575-45ca-8947-e2d432c521e4. Certificate must be in ‘us-east-1’. (Service: ApiGateway, Status Code: 400, Request ID: 15bee123-53f5-4f6a-b44e-940505c825d0, Extended Request ID: null)
這個錯誤最主要是以下的設定
ApiGatewayCustomDomainName.Properties.CertificateArn
此設定是針對 edge-optimized endpoint type,而此 type 只能使用us-east-1 的 ACM,因為是針對 worldwide,所以憑證上的 regional 要特別注意
另外 CustomDomainRecord.Properties.AliasTarget.DNSName 和 HostedZoneId 的設定也要注意,DistributionDomainName 和 DistributionHostedZoneId 也是針對 edge-optimized endpoint type
最後,如果是針對 Regional endpoint type,正確的 CloudFormation 的正確設定如下
AWSTemplateFormatVersion: "2010-09-09"
Description: "Setup API Gateway custom domain name"
Parameters:
AcmArn:
Type: String
CustomDomainName:
Type: String
ApiID:
Type: String
DomainHostZoneId:
Type: String
Resources:
ApiGatewayCustomDomainName:
Type: "AWS::ApiGateway::DomainName"
Properties:
EndpointConfiguration:
Types:
- REGIONAL
RegionalCertificateArn: !Ref AcmArn
DomainName: !Ref CustomDomainName
BasePathMapping:
Type: "AWS::ApiGateway::BasePathMapping"
DependsOn: ApiGatewayCustomDomainName
Properties:
DomainName: !Ref CustomDomainName
RestApiId: !Ref ApiID
Stage: dev
CustomDomainRecord:
Type: "AWS::Route53::RecordSet"
DependsOn: ApiGatewayCustomDomainName
Properties:
Name: !Ref CustomDomainName
Type: A
HostedZoneId: !Ref DomainHostZoneId
AliasTarget:
DNSName: !GetAtt ApiGatewayCustomDomainName.RegionalDomainName
HostedZoneId: !GetAtt ApiGatewayCustomDomainName.RegionalHostedZoneId
Custom Domain 另外要注意的地方
API Gateway 中的 Stage 設定若為 dev
,則整個 Invoke URL 大概長的像這樣,url 會自動加入 /dev 當成後綴
https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev
假設傳入的完整的 url 是這樣
https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/oauth/token
Lambda 那邊接到的 path 只有 /oauth/token ,相對的,如果 custom domain 是這樣
https://example.com/dev/oauth/token
那麼在測試時,會永遠得到 404 ,因為傳入 Lambda 時,path 會變成 /dev/oauth/token ,想當然爾,route 的判斷就會錯誤
所以在 CloudFormation 中的 BasePathMapping.Properties.BasePath 不要設定,就不會有這個問題