amplify cli で 作った Cloudfront + S3 にカスタムドメインを紐づける
amplify cli で構築した環境にカスタムドメインを紐づける方法を紹介します。
はじめに
AWS Amplify を使用すると、フロントエンド開発者でも簡単にインフラを構築できます。特に、公開時にカスタムドメインの設定が重要になることがあります。この記事では、Amplify CLI を使った S3 と CloudFront 環境へのカスタムドメインの紐付け方法について解説します。
前提
以下の前提で環境構築していることを想定しています。
- amplify cli を使ってインフラ構築
- フロントエンドは
amplify add hosting
でS3 + CloudFront
での構築 - API は
amplify add api
でREST API
を選択し、apigateway + lambda function
での構築
- フロントエンドは
- Route53 でドメインを取得
- Route53 でホストゾーンを作成
-
us-east-1
の ACM で証明書を取得。(cloudfront に紐づける証明書なのでus-east-1
で取得している必要があります。)
以下のドメインの証明書を取得しておきます。(my-domain.com
は自分のドメイン名に置き換えてください)my-domain.com
www.my-domain.com
*.my-domain.com
www.dev.my-domain.com
CloudFront へのカスタムドメインの設定
Cloudfront にカスタムドメインを紐づける方法について
amplify add hosting
を実行して S3 + CloudFront
での構築を選択すると、デフォルトでは AWS が用意しているドメイン(hoge.cloudfront.net
)が Cloudfront に紐づけられます。
またその際、プロジェクトのフォルダに amplify/backend/hosting/S3AndCloudFront/template.json
というファイルが作成されます。
このtemplate.json
は aws cloudformation
のテンプレートファイルです。
ここに cloudfront + s3
でのホスティング環境に関する設定情報が記載されています。
このtemplate.json
を編集してカスタムドメインを紐づけていきます。
もし、cloudformation を詳しく理解してからやりたい場合は、以下の記事が参考になります。
(あと chat gpt4 に聞くのもありです。なんでも質問していいので理解が早まります。)完成した template.json
まずは完成された template.json
を貼り付けます。(長いので折りたたみました)
最終的な `template.json`
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "{\"createdOn\":\"Linux\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.8.2\",\"stackType\":\"hosting-S3AndCloudFront\",\"metadata\":{}}",
"Parameters": {
"env": {
"Type": "String"
},
"bucketName": {
"Type": "String"
},
"customDomainName": {
"Type": "String",
"Default": "my-domain.com"
},
"acmCertificateArn": {
"Type": "String",
"Default": "arn:aws:acm:us-east-1:1234567890:certificate/hoge-huga"
},
"hostedZoneId": {
"Type": "String",
"Default": "Z0ABCDEFGHIG"
}
},
"Conditions": {
"ShouldNotCreateEnvResources": {
"Fn::Equals": [
{
"Ref": "env"
},
"NONE"
]
},
"IsProdEnv": {
"Fn::Equals": [
{
"Ref": "env"
},
"main"
]
}
},
"Resources": {
"S3Bucket": {
"Type": "AWS::S3::Bucket",
"DeletionPolicy": "Retain",
"Properties": {
"BucketName": {
"Fn::If": [
"ShouldNotCreateEnvResources",
{
"Ref": "bucketName"
},
{
"Fn::Join": [
"",
[
{
"Ref": "bucketName"
},
"-",
{
"Ref": "env"
}
]
]
}
]
},
"AccessControl": "Private",
"WebsiteConfiguration": {
"IndexDocument": "index.html",
"ErrorDocument": "index.html"
},
"CorsConfiguration": {
"CorsRules": [
{
"AllowedHeaders": [
"Authorization",
"Content-Length"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"MaxAge": 3000
}
]
},
"BucketEncryption": {
"ServerSideEncryptionConfiguration": [
{
"ServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
}
}
},
"PrivateBucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"DependsOn": "OriginAccessIdentity",
"Properties": {
"PolicyDocument": {
"Id": "MyPolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "APIReadForGetBucketObjects",
"Effect": "Allow",
"Principal": {
"CanonicalUser": {
"Fn::GetAtt": [
"OriginAccessIdentity",
"S3CanonicalUserId"
]
}
},
"Action": "s3:GetObject",
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "S3Bucket"
},
"/*"
]
]
}
}
]
},
"Bucket": {
"Ref": "S3Bucket"
}
}
},
"OriginAccessIdentity": {
"Type": "AWS::CloudFront::CloudFrontOriginAccessIdentity",
"Properties": {
"CloudFrontOriginAccessIdentityConfig": {
"Comment": "CloudFrontOriginAccessIdentityConfig"
}
}
},
"AddsIndexHtmlFunction": {
"Type": "AWS::CloudFront::Function",
"Properties": {
"Name": {
"Fn::Sub": "FrontEndEdgeFunction-${env}"
},
"AutoPublish": "true",
"FunctionConfig": {
"Comment": "Setting to add \"index.html\" to the access URL.",
"Runtime": "cloudfront-js-1.0"
},
"FunctionCode": "function handler(event) { var request = event.request; var uri = request.uri; if (uri.endsWith('/')) { request.uri += 'index.html'; } else if (!uri.includes('.')) { request.uri += '/index.html'; } return request; }"
}
},
"CloudFrontDistribution": {
"Type": "AWS::CloudFront::Distribution",
"DependsOn": [
"S3Bucket",
"OriginAccessIdentity"
],
"Properties": {
"DistributionConfig": {
"Aliases": [
{
"Fn::If": [
"IsProdEnv",
{
"Ref": "customDomainName"
},
{
"Fn::Sub": "${env}.${customDomainName}"
}
]
},
{
"Fn::If": [
"IsProdEnv",
{
"Fn::Sub": "www.${customDomainName}"
},
{
"Fn::Sub": "www.${env}.${customDomainName}"
}
]
}
],
"ViewerCertificate": {
"AcmCertificateArn": {
"Ref": "acmCertificateArn"
},
"SslSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2018"
},
"Comment": {
"Fn::Sub": "${bucketName}-${env}"
},
"HttpVersion": "http2",
"Origins": [
{
"DomainName": {
"Fn::GetAtt": [
"S3Bucket",
"RegionalDomainName"
]
},
"Id": "hostingS3Bucket",
"S3OriginConfig": {
"OriginAccessIdentity": {
"Fn::Join": [
"",
[
"origin-access-identity/cloudfront/",
{
"Ref": "OriginAccessIdentity"
}
]
]
}
}
}
],
"Enabled": "true",
"DefaultCacheBehavior": {
"AllowedMethods": [
"DELETE",
"GET",
"HEAD",
"OPTIONS",
"PATCH",
"POST",
"PUT"
],
"TargetOriginId": "hostingS3Bucket",
"ForwardedValues": {
"QueryString": "false"
},
"ViewerProtocolPolicy": "redirect-to-https",
"DefaultTTL": 86400,
"MaxTTL": 31536000,
"MinTTL": 60,
"Compress": true,
"FunctionAssociations": [
{
"EventType": "viewer-request",
"FunctionARN": {
"Fn::GetAtt": [
"AddsIndexHtmlFunction",
"FunctionARN"
]
}
}
]
},
"DefaultRootObject": "index.html",
"CustomErrorResponses": [
{
"ErrorCachingMinTTL": 300,
"ErrorCode": 400,
"ResponseCode": 200,
"ResponsePagePath": "/404/index.html"
},
{
"ErrorCachingMinTTL": 300,
"ErrorCode": 403,
"ResponseCode": 200,
"ResponsePagePath": "/404/index.html"
},
{
"ErrorCachingMinTTL": 300,
"ErrorCode": 404,
"ResponseCode": 200,
"ResponsePagePath": "/404/index.html"
}
]
}
}
},
"DNSRecord": {
"Type": "AWS::Route53::RecordSet",
"Properties": {
"HostedZoneId": {
"Ref": "hostedZoneId"
},
"Name": {
"Fn::If": [
"IsProdEnv",
{
"Fn::Sub": "${customDomainName}."
},
{
"Fn::Sub": "${env}.${customDomainName}."
}
]
},
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": {
"Fn::GetAtt": [
"CloudFrontDistribution",
"DomainName"
]
}
}
}
},
"DNSRecordWWW": {
"Type": "AWS::Route53::RecordSet",
"Properties": {
"HostedZoneId": {
"Ref": "hostedZoneId"
},
"Name": {
"Fn::If": [
"IsProdEnv",
{
"Fn::Sub": "www.${customDomainName}."
},
{
"Fn::Sub": "www.${env}.${customDomainName}."
}
]
},
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": {
"Fn::GetAtt": [
"CloudFrontDistribution",
"DomainName"
]
}
}
}
}
},
"Outputs": {
"Region": {
"Value": {
"Ref": "AWS::Region"
}
},
"HostingBucketName": {
"Description": "Hosting bucket name",
"Value": {
"Ref": "S3Bucket"
}
},
"WebsiteURL": {
"Value": {
"Fn::GetAtt": [
"S3Bucket",
"WebsiteURL"
]
},
"Description": "URL for website hosted on S3"
},
"S3BucketSecureURL": {
"Value": {
"Fn::Join": [
"",
[
"https://",
{
"Fn::GetAtt": [
"S3Bucket",
"DomainName"
]
}
]
]
},
"Description": "Name of S3 bucket to hold website content"
},
"CloudFrontDistributionID": {
"Value": {
"Ref": "CloudFrontDistribution"
}
},
"CloudFrontDomainName": {
"Value": {
"Fn::GetAtt": [
"CloudFrontDistribution",
"DomainName"
]
}
},
"CloudFrontSecureURL": {
"Value": {
"Fn::If": [
"IsProdEnv",
{
"Fn::Sub": "https://${customDomainName}"
},
{
"Fn::Sub": "https://${env}.${customDomainName}"
}
]
}
},
"CloudFrontOriginAccessIdentity": {
"Value": {
"Ref": "OriginAccessIdentity"
}
}
}
}
では、デフォルトのコードとの変更点を 1 つずつ見ていきます。
1.Parameters の設定
カスタムドメイン名、ACM 証明書の ARN、Route 53 のホストゾーン ID をパラメータとして定義します。これにより、複数回のハードコーディングを避け、変更が容易になります。
-
customDomainName
: Route53 で取得済みのカスタムドメイン名 -
acmCertificateArn
: ACM で取得した証明書の ARN。この証明書は cloudfront に紐づけるためus-east-1
リージョンで作成する必要があります。
https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/acm-regions.htmlAmazon CloudFront で ACM 証明書を使用するには、米国東部 (バージニア北部) リージョン の証明書をリクエスト (またはインポート) していることを確認します。CloudFront ディストリビューションに関連づけられたこのリージョンの ACM 証明書は、このディストリビューションに設定されたすべての地域に分配されます。
-
hostedZoneId
: Route53 で作成したホストゾーンの ID
実際に template.json に記載すると以下のようになります。
"Parameters": {
"env": {
"Type": "String"
},
"bucketName": {
"Type": "String"
},
+ "customDomainName": {
+ "Type": "String",
+ "Default": "my-domain.com"
+ },
+ "acmCertificateArn": {
+ "Type": "String",
+ "Default": "arn:aws:acm:us-east-1:1234567890:certificate/hogehoge"
+ },
+ "hostedZoneId": {
+ "Type": "String",
+ "Default": "hogehogeId"
+ }
},
2.Conditions の設定
次に Conditions
にIsProdEnv
という条件式を追加します。
このIsProdEnv
は名前の通り、本番環境かどうかを判定するための条件式です。
IsProdEnv
を使って、Cloudfront に紐づけるカスタムドメイン名を本番環境(my-domain.com
)と開発環境(${dev}.my-domain.com
)で分けるために使います。
"Conditions": {
"IsProdEnv": {
"Fn::Equals": [
{
"Ref": "env"
},
"main"
]
}
},
3.Resources の設定
次に Resources
で設定する項目を記載してきます。
このセクションは設定項目が多いので、用途ごとに分けて説明していきます。
S3Bucket の AccessControl を設定する
まず初めに、S3Bucket
のProperties
にAccessControl
を追加します。
こちら、どういう理由で設定したのか忘れてしまったのですが、これがないとamplify publish
でデプロイしたときにエラーになってしまったので、入れてます。。。
"Resources": {
"S3Bucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
+ "AccessControl": "Private",
}
}
}
公式では、「ほとんどのケースで設定が必要ないはずなので使うことは非推奨」と言われてるのでここは要調査項目ではあります。(あとで確認してみて理解ができたら記事を更新するかもです)
cloudfront にカスタムドメインを紐づける
次に本題の Cloudfront にカスタムドメインを紐づける設定をしていきます。
Cloudfront にカスタムドメインを紐づけるには以下の 2 つの設定が必要です。
-
AWS::CloudFront::Distribution
のAliases
にカスタムドメイン名を設定する -
AWS::Route53::RecordSet
のAliasTarget
に Cloudfront のドメイン名を設定する
"Resources": {
"CloudFrontDistribution": {
"Type": "AWS::CloudFront::Distribution",
"DependsOn": [
"S3Bucket",
"OriginAccessIdentity"
],
"Properties": {
"DistributionConfig": {
+ "Aliases": [
+ {
+ "Fn::If": [
+ "IsProdEnv",
+ {
+ "Ref": "customDomainName"
+ },
+ {
+ "Fn::Sub": "${env}.${customDomainName}"
+ }
+ ]
+ }
+ ],
+ "ViewerCertificate": {
+ "AcmCertificateArn": {
+ "Ref": "acmCertificateArn"
+ },
+ "SslSupportMethod": "sni-only",
+ "MinimumProtocolVersion": "TLSv1.2_2018"
+ },
// その他の設定
}
}
},
+ "DNSRecord": {
+ "Type": "AWS::Route53::RecordSet",
+ "Properties": {
+ "HostedZoneId": {
+ "Ref": "hostedZoneId"
+ },
+ "Name": {
+ "Fn::If": [
+ "IsProdEnv",
+ {
+ "Fn::Sub": "${customDomainName}."
+ },
+ {
+ "Fn::Sub": "${env}.${customDomainName}."
+ }
+ ]
+ },
+ "Type": "A",
+ "AliasTarget": {
+ "HostedZoneId": "Z2FDTNDATAQYW2",
+ "DNSName": {
+ "Fn::GetAtt": [
+ "CloudFrontDistribution",
+ "DomainName"
+ ]
+ }
+ }
+ }
+ },
}
注目すべき部分は以下のコードです。
{
"Fn::If": [
"IsProdEnv",
{
"Ref": "customDomainName"
},
{
"Fn::Sub": "${env}.${customDomainName}"
}
]
}
このコードはIsProdEnv
がtrue
の場合は${customDomainName}
を、false
の場合は${env}.${customDomainName}
を返すようになっています。
例えば、Parameters
セクションで設定した customDomainName
がmy-domain.com
の場合は
本番環境ではmy-domain.com
、開発環境では${env}.my-domain.com
という値になります。
開発環境時の${env}
には amplify env
でチェックアウト中の env
名が入ります。
これによって、開発環境ごとにドメイン名を分けることができます。
ex) dev.my-domain.com
、stg.my-domain.com
、my-domain.com(本番環境)
以上の設定で、cloudfront にカスタムドメインを紐づけることができました。
が、しかし、個人的には追加で設定したい項目もあるので、ついでに紹介します。
Cloudfront のディストリビューションに説明をつける
1 つは AWS::CloudFront::Distribution
のComment
です。
ここには Cloudfront の ディストリビューションの説明に記載する内容を設定できます。
デフォルトでは空白になっており、いくつかの環境を立ち上げた際に、各ディストリビューション ID がどの環境に紐づいているのかわかりにくいので、ここに環境名を設定しておくとわかりやすいです。
"Resources": {
"CloudFrontDistribution": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
+ "Comment": {
+ "Fn::Sub": "${bucketName}-${env}"
+ },
// その他の設定
}
}
},
}
私は${bucketName}-${env}
という形式で設定しましたが、${env}.${customDomainName}
にしてドメイン名を入れてもいいかもしれません。
cloudfront に www ドメイン名も紐づける
www をつけたドメイン名でもアクセスできるようにするために、www ドメイン名も cloudfront に紐づけます。
もし、amplify console hosting でカスタムドメインを紐づけていた場合は、www ドメイン名も自動で紐づけられていたと思いますので、amplify add hosting
に移行する場合は、この設定も忘れずに行った方がよいかもしれません。でないと、すでに www でアクセスしていたユーザーが直 URL でアクセスした際に 404 エラーになる可能性があります。
設定方法は「cloudfront にカスタムドメインを紐づける」とほぼ同じで www ありの設定が追加で必要なくらいですです。
「cloudfront にカスタムドメインを紐づける」で紹介したコードに対して追加のコードを記載します。
"Resources": {
"CloudFrontDistribution": {
"Type": "AWS::CloudFront::Distribution",
"DependsOn": [
"S3Bucket",
"OriginAccessIdentity"
],
"Properties": {
"DistributionConfig": {
"Aliases": [
{
"Fn::If": [
"IsProdEnv",
{
"Ref": "customDomainName"
},
{
"Fn::Sub": "${env}.${customDomainName}"
}
]
},
+ {
+ "Fn::If": [
+ "IsProdEnv",
+ {
+ "Fn::Sub": "www.${customDomainName}"
+ },
+ {
+ "Fn::Sub": "www.${env}.${customDomainName}"
+ }
+ ]
+ }
],
"ViewerCertificate": {
"AcmCertificateArn": {
"Ref": "acmCertificateArn"
},
"SslSupportMethod": "sni-only",
"MinimumProtocolVersion": "TLSv1.2_2018"
},
// その他の設定
}
}
},
"DNSRecord": {
"Type": "AWS::Route53::RecordSet",
"Properties": {
"HostedZoneId": {
"Ref": "hostedZoneId"
},
"Name": {
"Fn::If": [
"IsProdEnv",
{
"Fn::Sub": "${customDomainName}."
},
{
"Fn::Sub": "${env}.${customDomainName}."
}
]
},
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": {
"Fn::GetAtt": [
"CloudFrontDistribution",
"DomainName"
]
}
}
}
},
+ "DNSRecordWWW": {
+ "Type": "AWS::Route53::RecordSet",
+ "Properties": {
+ "HostedZoneId": {
+ "Ref": "hostedZoneId"
+ },
+ "Name": {
+ "Fn::If": [
+ "IsProdEnv",
+ {
+ "Fn::Sub": "www.${customDomainName}."
+ },
+ {
+ "Fn::Sub": "www.${env}.${customDomainName}."
+ }
+ ]
+ },
+ "Type": "A",
+ "AliasTarget": {
+ "HostedZoneId": "Z2FDTNDATAQYW2",
+ "DNSName": {
+ "Fn::GetAtt": [
+ "CloudFrontDistribution",
+ "DomainName"
+ ]
+ }
+ }
+ }
+ }
}
これで、www ドメイン名でもアクセスできるようになりました。
Cloudfront Functions で、Next.js の static サイトへのリクエストを正常に処理する
ほぼ完成かと思いきや、もう 1 つ設定が必要でした。
私が扱っているフロントエンドの構成だと、my-domain.com/hoge
にアクセスしてリロードした場合my-domain.com/
の内容が表示されてしまいます。
現象の原因(Chat GPT に聞いた結果)は以下の通りです。
S3 のデフォルトの挙動: S3 バケットでの静的ウェブサイトホスティングでは、リクエストされたパスに対応するファイルが存在しない場合、デフォルトでは「インデックスドキュメント」(通常は index.html
)が返されます。
CloudFront の挙動: CloudFront はリクエストを S3 バケットに転送しますが、リクエストされたパスに対応するオブジェクトが見つからない場合、S3 はインデックスドキュメントを返します。これが、/hoge
にアクセスしリロードした場合に root/index.html
の内容が表示される理由です。
また、私のアプリは Next.js の Static Export の機能を使って静的サイトとして構築しています。
更に next.config.js
でtrailingSlash: true
の設定を入れており、pages にあるファイルは全て パス/index.html
というファイル名として build されます。
つまり、本来はmy-domain.com/hoge
にアクセスした場合、my-domain.com/hoge/index.html
が返されるべきということになります。
ということで ↑ このルーティングの設定をしていきます。
実際のコードは以下です。
"Resources": {
+ "AddsIndexHtmlFunction": {
+ "Type": "AWS::CloudFront::Function",
+ "Properties": {
+ "Name": {
+ "Fn::Sub": "FrontEndEdgeFunction-${env}"
+ },
+ "AutoPublish": "true",
+ "FunctionConfig": {
+ "Comment": "Setting to add \"index.html\" to the access URL.",
+ "Runtime": "cloudfront-js-1.0"
+ },
+ "FunctionCode": "function handler(event) { var request = event.request; var uri = request.uri; if (uri.endsWith('/')) { request.uri += 'index.html'; } else if (!uri.includes('.')) { request.uri += '/index.html'; } return request; }"
+ }
},
"CloudFrontDistribution": {
"Type": "AWS::CloudFront::Distribution",
"DependsOn": [
"S3Bucket",
"OriginAccessIdentity"
],
"Properties": {
// その他の設定
"DistributionConfig": {
// その他の設定
"DefaultCacheBehavior": {
// その他の設定
+ "FunctionAssociations": [
+ {
+ "EventType": "viewer-request",
+ "FunctionARN": {
+ "Fn::GetAtt": [
+ "AddsIndexHtmlFunction",
+ "FunctionARN"
+ ]
+ }
+ }
+ ]
},
}
}
}
}
解説
-
AWS::CloudFront::Function
で/hoge/
にアクセスした場合に/hoge/index.html
を返す Cloudfront Function を作成
実際のコードは以下の通りですが、json 形式の cloudformation テンプレートに記載するために1行にしています。// FunctionCodeの中身。実際はjson形式のテンプレートに記載するためにtemplate.jsonでは1行にしています。 function handler(event) { var request = event.request var uri = request.uri if (uri.endsWith('/')) { request.uri += 'index.html' } else if (!uri.includes('.')) { request.uri += '/index.html' } return request }
-
上記
Cloudfront Function
をCloudfront
のDefaultCacheBehavior
に紐づける
これで晴れて my-domain.com/hoge
にアクセスした場合にmy-domain.com/hoge/index.html
が返されるようになりました。
4.Outputs の設定
最後に、Outputs
のカスタマイズになります。
amplify publish
を実行した際や、amplify status
を実行した際に、Cloudfront の URL がターミナルに表示されるのですが、デフォルトのままだと cloudfront の url(hoge.cloudfront.net
)が表示されるので、カスタムドメインを表示するようにします。
"Outputs": {
"CloudFrontSecureURL": {
"Value": {
- "Fn::Join": [
- "",
- [
- "https://",
- {
- "Fn::GetAtt": [
- "CloudFrontDistribution",
- "DomainName"
- ]
- }
- ]
- ]
+ "Fn::If": [
+ "IsProdEnv",
+ {
+ "Fn::Sub": "https://${customDomainName}"
+ },
+ {
+ "Fn::Sub": "https://${env}.${customDomainName}"
+ }
+ ]
}
},
}
ここはあまり重要じゃないですがやっておくとたまに便利だったりしますね。
さて、フロントエンドにカスタムドメインを紐づけるための設定は完了です。
ですが、API にもカスタムドメインを紐づけたいという需要もあるんじゃないかと思います。
次のセクションでその手順をお伝えします。
REST API(Apigateway)にもカスタムドメインを紐づける
ここでは amplify add api
で構築した REST API
にカスタムドメインを紐づける方法を紹介します。
amplify add api
でREST API
を選択すると、apigateway + lambda function
でリソースが構築されてます。
apigateway にカスタムドメインを紐づけるには以下の 3 つの設定が必要です。
- apigateway にカスタムドメインの証明書をつける
- route 53 で A レコードを設定
- apigateway でマッピング設定をする
この辺りは以下の記事が大変参考になりましたので、詳しくはこちらの記事の解説を参照してみてください 🙇♂️
私の方からは上記で設定したカスタムドメインをフロントエンドから利用する手順を紹介します。
amplify で REST API
を構築した場合、大体の方は API へのアクセスを以下のようなコードで行っていると思います。
import { API } from 'aws-amplify'
const getHoge = async () => {
return API.get('myApiName', '/hoge')
}
デフォルトの設定のままだと、内部でリクエストに使われる URL は以下のよう apigateway の URL がそのまま使われています。
https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/dev/hoge
このリクエスト URL を先ほど apigateway に設定したカスタムドメインにするには
Amplify.configure(awsExports)
している部分で rest api の endpoint を以下のように置き換えます。
import { Amplify } from 'aws-amplify'
Amplify.configure({
...awsExports,
aws_cloud_logic_custom: awsExports.aws_cloud_logic_custom.map((item) => {
if (item.name === 'myApiName') {
return {
...item,
endpoint: 'api.my-domain.com',
}
}
return item
}),
})
こうすることでフロントエンドから aws-amplify
ライブラリのコードを使って API アクセスする際に、api.my-domain.com
が使われるようになります。
まとめ
この記事では、amplify cli で構築した環境にカスタムドメインを紐づける方法を紹介しました。
自分の備忘録やだれかの参考になれば幸いです。
Discussion