この記事では、独自ドメインからCloudFront経由でS3にアクセスする静的ファイルホスティングサービスの作り方について解説します。
サービスアーキテクト
以下の図が今回説明するサービスの設計になります。
- お名前.comでホスティング用のドメイン名を登録する
- Route53でお名前.comで登録したドメインの名前解決を行い、CloudFrontにアクセスする
- CloudFrontからS3にアクセスする
- S3のホスティングURLには直接アクセスはできないようにする
S3のバケットを作成する
AWSコンソールにアクセスし、「S3」から「Create Bucket」でバケットを作成します。
以下は詳細の設定です。(その他はデフォルトで大丈夫です)
- ACLsはdisabledにする
- Block Public Access SettingsはBlock all public accessにする
バケットにファイルを追加する
静的ホスティングしたいファイルをバケットに追加します。
CloudFrontを作成する
次にCloudFrontを作成し、割り当てられたドメインからS3にアクセスできるようにします。
コンソールで「CloudFront」から「Create distribution」で新規作成します。
以下が詳細の設定です。(その他はデフォルトで大丈夫です)
- Origin domainには作成したS3バケットのドメインを指定する
- Origin AccessではLegacy access identitiesを指定する
- Origin access identityは「Create New OAI」で新規作成したものを指定する
- Bucket Policyは「Yes, update the bucket policy」を指定する
作成したら、デプロイが完了するまで少し時間がかかるので待ちます。
ルートアクセスでindex.htmlを表示するように関数を作成する
作成したDistribution Domain(d2xxxxx.cloudfront.net)にアクセスを試みてみると、AccessDeniedとなります。
正しくはd2xxxx.cloudfront.net/index.htmlとしてアクセスしないと表示されないようです。
これはちょっと不格好なので、index.htmlの指定なしでアクセスできるようにします。
サイドバーの「Functions」から関数を新たに作成します。
関数は以下のように「/」へアクエスしたら「index.html」を追加する処理にします。
1 2 3 4 5 6 7 8 9 10 |
function handler(event) { var request = event.request; var uri = request.uri; // Check whether the URI is missing a file name. if (uri.endsWith('/')) { request.uri += 'index.html'; } return request; } |
作成したら、「Publish」から関数を発行します。
作成したDIstrubutionの「Behavior」から「Edit」で次のように作成した関数を割り当てます。
動作確認
ここまでで動作確認をします。
- CloudFrontのDistribution Domain(d2xxxxxx.cloudfront.net)へのアクセス→index.htmlが表示される
- S3のバケットURL(xxxx.s3.xxxx.amazonaws.com)へのアクセス→AccessDeniedとなる
お名前.comでドメインを作成する
次は独自ドメインでCloudFrontにアクセスできるための設定をしていきます。
まずはお名前.comでドメインを作成します。
Route53でも作成は可能なのですが、お名前.comの方が安い(多分)のでそっちで作るのが良いと思います。
Route53でホストゾーンとNSレコードを作成し、お名前.comの方に割り当てる
次にお名前.comで登録したドメインをRoute53で名前解決をするために、Route53を設定します。
まずはホストゾーンを作成します。
- Domain Nameにはお名前.comで登録したドメイン名を指定します
- その他はデフォルトで大丈夫です
ホストゾーンを作成したらNSレコードが作成されていますので、これをお名前.comのDNS設定に割り当てます。
お名前.comのサイドバーの「ネームサーバーの変更」から作成したドメインを選択し、「他のネームサーバを利用」のタブでネームサーバーを入力します。
Route53の最後の「.(ピリオド)」は不要なのでそこは省きます。
動作確認
お名前.comで作成したドメインがRoute53で名前解決されているかの確認はdig
コマンドで行います。
次のようにNSレコードが割り当てられているかを調べます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ dig shiro-s3-hosting-sample.net NS ; <<>> DiG 9.10.6 <<>> shiro-s3-hosting-sample.net NS ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46715 ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;shiro-s3-hosting-sample.net. IN NS ;; ANSWER SECTION: shiro-s3-hosting-sample.net. 86385 IN NS ns-1427.awsdns-50.org. shiro-s3-hosting-sample.net. 86385 IN NS ns-1712.awsdns-22.co.uk. shiro-s3-hosting-sample.net. 86385 IN NS ns-228.awsdns-28.com. shiro-s3-hosting-sample.net. 86385 IN NS ns-612.awsdns-12.net. ;; Query time: 58 msec ;; SERVER: 192.168.3.1#53(192.168.3.1) ;; WHEN: Sun Apr 02 19:50:13 JST 2023 ;; MSG SIZE rcvd: 193 |
正しく設定されている場合、ANSWER SECTIONに4つのNSレコードが登録されているのを確認できるでしょう。
独自ドメインに証明書をACM(AWS Certificate Manager)で割り当てる
CloudFrontに割り当てた独自ドメインはHTTPSアクセスが必須になっています。
そのため、証明書をACMで作成します。
コンソールで「ACM」にアクセスし、「Request certificate」から作成します。
- Fully qualified domain nameにはお名前.comで作成したドメイン名を指定します
- それ以外はデフォルトで大丈夫です
作成した証明書を選択するとステータスが「Pending Validation」となっているため、「Create records in Route 53」でRoute53にDNS検証用のCNAMEレコードを作成します。
CNAMEレコードを作成しても検証できるまでには、結構時間がかかりますのでしばらく待ちます。
正しく適用できているかはdigコマンドで確認できます。
1 2 |
$ dig +short _9e8adbb0f9b7c07ef0d277f2193e7bfd.shiro-s3-hosting-sample.net _b0eaad10e2a41dca70f20b0473ec3666.sggfvksfyf.acm-validations.aws. |
CloudFrontでAlternate domain nameとCustom SSL Certificateを設定する
次はCloudFrontで作成したDistrubutionの代替ドメイン名とSSL証明書を設定します。
- Alternate domain nameにお名前.comで作成したドメイン名を指定します
- Custom SSL certificateにACMで作成した証明書を指定します
- それ以外はデフォルトで大丈夫です
Route53でCloudFrontに繋げるためのAレコードを作成する
最後にRoute53でCloudFrontに繋げるためのAレコードを作成します。
Route53でのAレコードはIPアドレスだけではなく、AWSのリソースのエイリアスを指定することができます。
以下のようにRoute53にアクセスし、「Create Record」からCloudFront向けのAレコードを作成します。
- Record TypeはAレコードを指定します
- AliasスイッチをONにします
- Route traffic toをAlias to Cloudfront distributionを指定します
- CloudFrontのDistributionに作成したものを指定します
動作確認
これで独自ドメインからS3へ保存した静的ファイルへのアクセスが可能となりました。
1 2 3 4 5 6 7 8 9 10 |
$ curl https://shiro-s3-hosting-sample.net <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body> <h1>Hello World</h1> </body> </html> |
まとめ
今回はS3にホスティングした静的ファイルへ独自ドメインからアクセスできるための手順を紹介しました。
S3、CloudFront、ACM、Route53など色々なサービスを組み合わせる必要があるので複雑な部分もありますが参考になれば幸いです。