メンチカツには醤油でしょ!!

AWS/Java/Node.js/Spreadsheets/Docker/Jenkins/コミュニティ・勉強会レポを主とした技術系ブログ

S3でhttpsをホスティングするためにCloudFront+ACMを利用する

S3のホスティングhttps化する

(2017/08 現在)
静的なウェブサイトなどをホスティングする際にはS3が超便利で今はこれ以外の選択肢が考えられないほどですが、このS3でホスティングしているサイトをAmazon CloudFrontACM(AWS Certificate Manager)を使ってhttps化します。

http://www.your-domain.com.s3-website-ap-northeast-1.amazonaws.com/
↓ (こんな感じ) ↓
https://www.your-domain.com/

前提

・S3でサイトはアップロード済
・独自メイン取得済 (お名前.comとかでも良い、Route53は必須ではない)
Amazon SESなどを利用して独自ドメインのメール送受信はできる状態

ちなみに、ドメインの取得は後からにして、とりあえずCloudFrontを設定してみるって方は一部の設定を飛ばせばCloudFront⇒S3という流れは作れますし、あとから追加で設定を入れることも可能です。

ドメインにメール受信設定がされていない場合はこちらの記事も参考にしてください。

S3の設定 - バケット命名

S3の独自ドメイン名はホスティング予定のドメイン名と合わせましょう。
今回は前述の例のように、取得したドメインがyour-domain.comで、S3のバケット名がwww.your-domain.comとして話を進めます。

先にACMの設定を!

先にACM(AWS Certificate Manager)の設定をしないと、CloudFrontの設定最中にACMの設定が割り込んでしまい煩雑になるので先にACM設定をしちゃいます。
なおこの順番はマストではなく推奨です。

証明書のリクエスト - ACM設定

リージョンはバージニア北部(us-east-1)が選択されていることを確認してください。
ドメイン名を *.your-domain.com で入力して、確認とリクエスト ボタンを押下します。
すると、ドメイン宛にメールが送られてきます。
f:id:ryoichi0102:20170807150930p:plain

メール内のリンクを踏んでI Approveボタンを押下します。
Success! 画面に遷移すればACMの設定は完了です。
f:id:ryoichi0102:20170807150949p:plain

CloudFront 設定

コンソールでCloudFrontの画面に行き、Create Distributionボタンを押下します。
f:id:ryoichi0102:20170807151238p:plain

Select a delivery method for your content.

今回はWebですのでWeb側の方のGet Startedボタンを押下します。
f:id:ryoichi0102:20170807151436p:plain

Create Distribution

キャプチャは長いですが、キャプチャの下に書き換える所を纏めてあります。
f:id:ryoichi0102:20170807152822j:plain

Origin Settingsセクション

Origin Domain Name : S3のバケット名を一部入力すればアシストが表示されますので、選択。www.my-domain.com.s3.amazonaws.comという形式に。

Origin Path : ルートに配置しているindex.htmlをhttps://www.my-domain.com/で表示させる前提の場合は空で。入力する場合は/始まりです。

Origin ID : Origin Domain Nameを選択すると、自動的に入力されると思います。S3-www.your-domain.comのような形式。

Restrict Bucket Access : バケットへのアクセスを制限する場合はYesに。設定後は基本S3ではなくCloudFrontからアクセスすると思いますので、Yesに。

Origin Access Identity : Create a New Identityのまま。Commentは空のままで良い。

Grant Read Permissions on Bucket :バケットへの読取権限を与えるかどうか。Noを選択すると自分でやらないといけなくなるので、Yes, Update Bucket Policyを選択します。

Default Cache Behavior Settings セクション

Viewer Protocol Policy : Redirect HTTP to HTTPS、HTTPへのアクセスをHTTPSにリダイレクトするのでこれを選択します。

Distribution Settings セクション

Alternate Domain Names (CNAMEs) : www.your-domain.comのように(後続の手順でDNSレコードのCNAMEとして登録する値を指定します。

SSL Cretificate : 前述のACM設定を先にしていないと、Default CloudFront Distributionが選択されておりCustom SSL Certificateが選択できず、Request or Import a Certificate with ACMボタンを押下しこれを先に設定することになり面倒です。(東京リージョンだけACM設定している場合などもこうなります。)
ACM設定は既にあると思いますので、Custom SSL Certificateを選択し対象のドメインを選択します。

Default Root Object : index.htmlなどhttps://www.your-domain.com/で指定した場合に表示されるページ(htmlなど)を指定します。

最下部のCreate Distributionボタンを押下すると画面が遷移しますが、まだ完了してません。
f:id:ryoichi0102:20170807153715p:plain

In ProgressがDeployedになれば完了です。
数分かかるかも知れません。
f:id:ryoichi0102:20170807153828j:plain

CloudFront 動作確認

コンソールよりID(Distribution ID)をクリックすると詳細画面に遷移します。
その中で、Domain Nameと記載ある所に、CloudFrontのサブドメインが表示されています。これがCloudFrontを介したドメイン名です。
http://a1b2c3d4e5f6.cloudfront.net/ にアクセスして
https://a1b2c3d4e5f6.cloudfront.net/ にリダイレクトされることを確認しましょう。

f:id:ryoichi0102:20170807154552j:plain

表示されない場合 : Access Denied

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<script/>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>A1B2C3D4E5F6G7H8</RequestId>
<HostId>***************************************************************************=</HostId>
</Error>

http://a1b2c3d4e5f6.cloudfront.net/ がダメで、http://a1b2c3d4e5f6.cloudfront.net/index.html なら表示される場合は前述のDefault Root Objectの設定が原因と思われます。

ドメインDNSレコード設定

www.your-domain.com の CNAME に a1b2c3d4e5f6.cloudfront.net (さきほどCloudFrontでDomain Nameに表示されていた値)を設定します。

繋がらない場合 : The request could not be satisfied.

ERROR The request could not be satisfied.
Bad Request
Generated by cloudfront (CloudFront)
Request ID: ~~~

と出る場合は、前述のAlternate Domain Names (CNAMEs)が設定されていない可能性がありますので確認してください。