【JAWS-UG関西女子会】#1 Amazon S3＋CloudFrontで静的WEBサイトを高速化させよう

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-65307172-1', 'auto');
  ga('send', 'pageview');

</script>

#はじめに
この記事はJAWS-UG関西女子会「はじめて女子応援企画！事例から学ぶもくもく＆もぐもぐ会」で
 ~~もぐもぐ~~ [^1] もくもくする際のテキストとなります。
[^1]: 節子！それは懇親会や！！


#本記事での目標

* Amazon S3にWEBサイト表示用のファイル置き場をつくること
* S3とCloudFrontを連携させてサイトアクセスの高速化すること

以下のような構成となります。
![ELB000300.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/80dec25f-3a0b-dd14-7cc2-cca003a654c0.jpeg)



#Amazon S3にWEBサイト表示用のファイル置き場をつくること
###S3にWEBサイト表示用のファイル置き場を作るまでのながれ

1. WEBサイト用にS3のバケットを作る
2. バケットにファイルをアップロードする
3. 設定確認をする


#S3の用語について
<dl>
  <dt>S3：</dt>
  <dd>Simple Storage Serviceの略</br>
<dd>略称だけどみんなS3って言ってる</dd><br>
  <dt>バケット：</dt>
  <dd>S3上に作るフォルダ的なもの</br>
　<dd>名前がユニークである必要あり</br>
　<dd>1アカウントあたり最大100個まで</dd><br>
<dt>オブジェクト：</dt>
<dd>ファイルのこと<br>
<dd>URLによるアドレスが付与</br>
<dd>バケット内に容量無制限で置くことができる</br>
<dd>1オブジェクトのサイズは最大5TBまで</dd><br>
<dt>WEBサイトエンドポイント：</dt>
<dd>S3上のオブジェクトへアクセスするためのURLのこと<br>
<dd>エンドポイントは自動的に割り当てられる</br>
<dd>※本手順では独自ドメインとの割当て方は省いています。<br>
<dd>独自ドメインをしたい場合はサポートメンバーに言ってください！！</dd>
</dl>

#Amazon S3での設定手順
##1.WEBサイト用にS3のバケットを作る
WEBサイトのファイル置き場としてS3にバケットを作ります。

<p>　</p>
1.1.メニューからS3をクリックします
![AWS000116.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/9c33f80c-0792-b81c-5e3a-30a692e9f6a9.jpeg)

<p>　</p>
1.2.Create Bucketをクリックします。
なにか見えてるのは元々作ってたバケットなので気にしないでください
![AWS000117.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/2ec0cab6-6598-97cb-0394-8a30dab9e19f.jpeg)
<p>　</p>
1.3.Bucket Nameに好きなバケット名を入れて下さい。
世界中でユニークである必要があるので、他とかぶらなさそうなものにしてください
例では「mokumokugirls」としています
![AWS000118.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/1b9ad607-09c1-f06f-e585-bb5544a2f51f.jpeg)
<p>　</p>
1.4.バケット名を入れたらCreateボタンをクリックします
![AWS000119.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/3ba70b86-152d-66b5-d72f-f89e479dfe90.jpeg)

<p>　</p>
1.5.バケットが出来上がりました
![AWS000120.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/01de9f35-331b-db23-cb37-b702eb066977.jpeg)

##2.バケットにファイルをアップロードする
実際に表示させるファイルをS3のバケットにアップロードします。

<p>　</p>
2.1.アップロード用のファイルを3つ用意します。

* index.html(サイトのトップページ)
* error.html(ファイルがないURLを指定された場合のエラーページ)
* index.htmlに貼る画像ファイル(てきとーな画像を用意して下さい)

index.htmlの中身は以下の様な感じにしました。
メモ帳等で作って下さい。
自分のだとわかりやすいように「Hello World!!」の文字列の部分を変えてみましょう。
画像ファイルの名前も合わせて下さい。

```index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 "http://www.w3.org/TR/html4/strict.dtd">

<html>

 <head>
  <title>JAWS-UG関西女子会もくもく勉強会</title>
 </head>

 <body>
  <!--文字列をオリジナルなものに変えてみましょう-->
  <span style="font-size : 100pt">Hello World!!</span></br>
  
  <!--画像ファイル名を自分で用意した画像ファイル名と合わせましょう-->
  <img src="./kansaigirls.jpg" width="500" height="500">
 </body>

</html>
```

存在しないファイル名を指定された時に表示するerror.htmlの内容は以下の様な感じにしました。
こちらも内容をわかりやすいように変えてみましょう。
画像ファイルの名前も合わせて下さい。

```error.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 "http://www.w3.org/TR/html4/strict.dtd">

<html>

 <head>
  <title>JAWS-UG関西女子会もくもく勉強会</title>
 </head>

 <body>
  <!--文字列をオリジナルなものに変えてみましょう-->
  <span style="font-size : 50pt">Sorry!! Forbidden!!</span></br>

  <!--画像ファイル名を自分で用意した画像ファイル名と合わせましょう-->
  <img src="./kansaigirls.jpg" width="500" height="500">
 </body>

</html>
```

<p>　</p>
2.2.できあがったバケット名のリンクをクリックします。
![AWS000121.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/159bc7f0-fede-426c-516e-64e292949f0b.jpeg)


<p>　</p>
2.3.「Upload」ボタンをクリックします。
![AWS000122.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/034530c6-8264-b873-3a00-420d1177b313.jpeg)

<p>　</p>
2.4.アップロードするファイルを選んで・・・
![AWS000123.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/12247c34-d75f-4ab5-0fd3-c8da0effabc3.jpeg)

<p>　</p>
2.5.「Drag and drop files and folders to upload here」の枠内にドラッグアンドドロップして
「Start Upload」ボタンをクリックします。
![AWS000124.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/da0b108a-88a9-d836-dac8-dbd79c93eacb.jpeg)


<p>　</p>
2.6. ファイル3つともTransfersタブ上で「Done」となったことを確認します。
![AWS000125.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/64388f45-2ea0-9172-cdc7-c9b83e425949.jpeg)


##3.設定確認をする
この状態ではまだWEBサイトを表示できないことを確認してみましょう。

<p>　</p>
3.1.index.htmlをクリックします。
![AWS000146.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/959c80d3-8d27-7968-24e7-02509ae87b5c.jpeg)

<p>　</p>
3.2.Propertiesボタンをクリックして「Link」に表示されているURLに鍵マークが付いていることを確認します。
![AWS000147.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/f9811b3e-769a-e61a-6b4b-ac24cf78624b.jpeg)


<p>　</p>
3.3.URLをクリックしてページがアクセス拒否され、表示できないことを確認します。
![AWS000148.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/6c617a84-be13-8a45-7685-6f9c6ffafb3d.jpeg)


<p>　</p>
3.4.バケット名をクリックします。
![AWS000149.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/8525988e-19ed-5015-9396-574e7dfd3316.jpeg)


<p>　</p>
3.5.Propertiesの「Static Website Hosting」を展開し「Endpoint」に表示されているURLをクリックしてみましょう。
![AWS000150.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/d5f64fe8-86a9-856d-0f69-5b30c6f24e01.jpeg)

<p>　</p>
3.6.ページに404 Not Foundが表示されていることを確認します。
![AWS000151.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/0d510943-3190-1fd4-9a15-09f5bfe09d1a.jpeg)


<p>　</p>
**お疲れ様です！ここまでで半分です！**


#S3とCloudFrontを連携させてサイトアクセス高速化すること
###S3とCloudFrontを連携させるまでのながれ

1. ディストリビューションの作成
2. 設定確認
3. デフォルトルートオブジェクトの設定
4. カスタムエラーページの設定

#CloudFrontの用語について
<dl>
  <dt>CloudFront：</dt>
  <dd>AWSのCDNサービス名称のこと<br>
  <dd>配信するサイトのキャッシュを世界中のエッジロケーションに持たせることにより<br>
  <dd>サイトの高速配信とアクセス集中時の負荷を減らす、地域指定によるアクセス制御等ができる</dd><br>
  <dt>エッジロケーション：</dt>
  <dd>CloudFrontで配信するキャッシュを保持するサーバが配置されている場所のこと</dd><br>
  <dt>ディストリビューション：</dt>
  <dd>CloudFrontの配信設定のこと</dd><br>
<dt>デフォルトルートオブジェクト：</dt>
<dd>CloudFrontに割り当てられたドメイン名のみでアクセスした際に表示するファイルを指定する<br>
<dd>通常はindex.htmlを指定する</dd><br>
<dt>オリジン：</dt>
<dd>CloudFrontで配信するサイトの「元」のこと<br>
<dd>S3でもEC2インスタンスでも設定可</dd><br>
<dt>オリジンアクセスアイデンティティ：</dt>
<dd>オリジンへのアクセス制御のこと</dd><br>
<dt>バケットポリシー：</dt>
<dd>S3のバケットに対するアクセス制御のこと</dd><br>
<dt>S3:GetObject：</dt>
<dd>S3に対するアクセス制御で「オブジェクトの読み取りのみ」を意味する</dd>
</dl>

#CloudFrontでの設定手順
##4.ディストリビューションの作成
WEBサイト用のバケットのなかみをCloudFrontで配信するように設定します。

<p>　</p>
4.1.左上のBOXマークをクリックしてメニューを表示させます。
![AWS000152.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/b72c8677-19c2-cf39-9c14-6f1538041feb.jpeg)

<p>　</p>
4.2.メニューより「CloudFront」をクリックします。
![AWS000153.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/a9f7aaa1-e01c-8a99-0c0c-410aa710ca1f.jpeg)

<p>　</p>
4.3.ディストリビューションを作成します。
「Create Distribution」ボタンをクリックします。
![AWS000154.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/96233545-ba07-d706-622a-ceba5eda0744.jpeg)

<p>　</p>
4.4.「Web」と「RTMP [^2] 」のうち「Web」の「Get Started」ボタンをクリックします。
[^2]: Real Time Messaging Protocolの略。Adobe Flashで音声や動画などのストリーミング再生を行うのに使われる通信プロトコル。ストリーミングメディアの高速配信を行いたい場合はRTMPのディストリビューションを作成する。
![AWS000155.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/f692996c-3e37-9465-be22-0833c7340a5a.jpeg)

<p>　</p>
4.5.「Origin Domain Name」のテキストボックスをクリックするとバケット名がドロップボックス表示されるので
作成したS3バケット名が入っているものをクリックします。
![AWS000156.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/98d7a80f-f060-5fef-5fee-4e183c257cf6.jpeg)

<p>　</p>
4.6.デフォルトでは「Restrict Bucket Access」が「No」となっているので「Yes」をクリックします。
![AWS000157.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/3ad9a5d4-af58-b71a-935b-3a59e623be0b.jpeg)

<p>　</p>
4.7.「Origin Access Identity」が「Create New Identity」となっていることを確認し
「Comment」に表示されている文字列を自分のわかりやすい文字列に変更して下さい。
![AWS000158.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/cac57753-da1e-1615-c1ed-6d100e233125.jpeg)

<p>　</p>
4.8.「Grant Read Permissions on Bucket」を「Yes, Update Bucket Policy」に変更して下さい。
![AWS000159.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/7ccbcd33-f980-a0d8-bb25-297de9c7847e.jpeg)

<p>　</p>
4.9.「Create Distribution」ボタンをクリックします。
![AWS000160.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/fa26b2ab-a036-7092-f49d-051aba06a177.jpeg)

<p>　</p>
4.10.ディストリビューションの作成が開始されます。
![AWS000161.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/23ea9d78-7da4-a986-3697-3b1af00dfb9d.jpeg)

<p>　</p>
4.11.左メニューの「Distributions」をクリックします。
![AWS000162.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/153e0cf5-2003-8c59-0357-bd51f3bf7526.jpeg)

<p>　</p>
4.12.「Status」欄が「In Progress」となっている間は作成中です。
![AWS000167.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/ac698dba-e7c2-481b-b1a0-e52ac4d0bd25.jpeg)

<p>　</p>
4.13.「Status」が「Deployed」となるとディストリビューションの作成完了です。
![AWS000168.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/78bb70f9-583e-727b-4d71-1247d364c77b.jpeg)

<p>　</p>
##5.設定確認
CloudFrontでの配信設定が正しくできているか確認をします。

<p>　</p>

5.1.リンク表示されているIDを~~メモします。~~クリックします
Originsタブをクリックして「Origin Access Identity」欄に表示されている「origin-access-identity/cloudfront/E2IRLCVGYRGKFP」の「origin-access-identity/cloudfront/＜ここ＞」のIDをメモします。
![AWS000169.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/d9a6bc53-4aaa-e0c1-9e64-de284e7ec064.jpeg)

<p>　</p>
5.2.S3バケットのPropertiesで「Permissions」クリックして展開します。
バケット作成直後は「Add bucket policy」となっているのが「Edit bucket policy」となっていることを確認します。
「Edit bucket policy」ボタンをクリックします。
![AWS000165.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/a22bdef5-0a54-61b1-dd2e-91362c5ff555.jpeg)

<p>　</p>
5.3.ポリシーエディターでCloudFrontのOrigin Access Identityが先ほどメモをした~~CloudFront~~Origin access IdentityのIDと同じであることを確認します。
また、許可されているActionが「S3:GetObject」となっており、リソースにS3バケット名が入っていることを確認します。
![AWS000166.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/b13d499e-b0a3-0fac-3506-3d2a9641c163.jpeg)

<p>　</p>
5.4.CloudFrontのページに戻り、左メニューで「Distributions」をクリックします。
![AWS000162.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/153e0cf5-2003-8c59-0357-bd51f3bf7526.jpeg)

<p>　</p>
5.5.リンク表示されているIDをクリックします。
![AWS000169.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/d9a6bc53-4aaa-e0c1-9e64-de284e7ec064.jpeg)

<p>　</p>
5.6.「Domain Name」をコピーします。
![AWS000176.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/94effe98-6727-333f-d3d3-601e8e6d39f2.jpeg)

<p>　</p>
5.7.ブラウザのURL欄にコピーしたドメイン名を貼り付け、その後ろに「/index.html」を追加してページが表示されるかを確認します。
![AWS000171.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/4fb9ac73-98c7-57d5-ccce-ffaa1af084df.jpeg)

<p>　</p>
##6.デフォルトルートオブジェクトの設定
手順5の段階ではドメイン名でアクセスをしてもindex.htmlは自動的に表示されないので、デフォルトで表示させるファイルindex.htmlに指定する設定を行います。

<p>　</p>
6.1.先ほどのページに戻り「Edit」ボタンをクリックします。
![AWS000170.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/4cb9a766-81e4-8aed-ee2b-782ab04a8897.jpeg)

<p>　</p>
6.2.「Default Root Object」に「index.html」と入力します。
![AWS000173.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/5c426566-759a-12c9-f2b2-e9b7f7067883.jpeg)

<p>　</p>
6.3.「Yes, Edit」ボタンをクリックします。
![AWS000173_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/85659/7ed5cc4a-602d-51b7-7a70-179cd95065a2.jpeg)

<p>　</p>
6.4.「CloudFront Distributions」リンクをクリックします。
![AWS000175.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/37ca670b-66fd-48a1-543d-19914411ac05.jpeg)

<p>　</p>
6.5.「Status」が「In Progress」の間は設定中のため「Deployed」になるまで待ちます。
![AWS000168.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/78bb70f9-583e-727b-4d71-1247d364c77b.jpeg)

<p>　</p>
6.6.「Deployed」になったらブラウザでドメイン名のみでアクセスしてページが表示されるかを確認します。
![AWS000177.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/dd558062-82a5-4838-ab0a-06e89e839ed1.jpeg)

<p>　</p>
##7.カスタムエラーページの設定
ファイルが無い場合等に表示するエラーページを、自分で用意したファイルとする設定を行います。

<p>　</p>
7.1.「Distributions」でIDリンクをクリックした後「Error Pages」タブをクリックします。
![AWS000178.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/1d8592aa-8cd7-1c51-47d2-598ae8322965.jpeg)

<p>　</p>
7.2.「Create Custom Error Response」ボタンをクリックします。
![AWS000179.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/d999ca6a-b7d1-fc9a-08c9-2ecf15684482.jpeg)

<p>　</p>
7.3.今回作成したerror.indexの内容はページがない旨を示す内容のため「HTTP Error Code」では「403 Forbidden」を選択します。
![AWS000189.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/d3b388c8-757d-c62f-dfe2-5a17814c1cd3.jpeg)

<p>　</p>
7.4.デフォルトでは「Customize Error Response」が「No」になっているため「Yes」にチェックを入れます。
![AWS000192.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/c41fb5ba-856b-2271-f5de-e9266f90f8ae.jpeg)


<p>　</p>
7.5.「Response Page Path」に「/error.html」と入力します。
![AWS000193.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/d68705b0-e57c-152f-a33d-257b38da94dc.jpeg)

<p>　</p>
7.6.「HTTP Response Code」で「403 Forbidden」を選択します。
![AWS000190.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/c0148043-18a2-e65d-5d40-5b4d77734ffd.jpeg)

<p>　</p>
7.7.「Create」ボタンをクリックします。
![AWS000194.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/3226f55b-b964-63eb-0a4d-bb64e6de7bf2.jpeg)

<p>　</p>
7.8.作成が開始されます。
![AWS000185.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/b57ab7b5-dbaf-46ab-4f09-ea96774e3e1c.jpeg)

<p>　</p>
7.9.「CloudFront Distributions」リンクをクリックします。
![AWS000175.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/37ca670b-66fd-48a1-543d-19914411ac05.jpeg)

<p>　</p>
7.10.「Status」が「In Progress」の間は設定中のため「Deployed」になるまで待ちます。
![AWS000168.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/78bb70f9-583e-727b-4d71-1247d364c77b.jpeg)

<p>　</p>
7.11.「Deployed」になったらブラウザでドメイン名の後ろに存在しないファイル名を付けてアクセスしてエラーページが表示されるかを確認します。
※今回の設定ではS3への直接アクセス不可としているせいなのか、通常存在しないページのアドレスを指定した場合は「404 Not Found」が返ってくるのが「403 Forbidden」が返ってきます。
![AWS000195.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/2c7cf146-4cc1-7445-0ab7-49c5156583b0.jpeg)

7.12.今回は「403 Forbidden」用のみを設定しましたが、本番運用する場合はすべてのエラーコードに対応したページを用意し、各エラーコード分のカスタムエラーページを設定します。
![AWS000186.JPG](https://qiita-image-store.s3.amazonaws.com/0/85659/a4253f12-e6e7-f7cc-c5f2-0bfed52b5a61.jpeg)


以上で、CloudFrontでサイトアクセスを高速化させたS3静的WEBサイトの完成です。
サイトのURLを独自ドメインに付け替える作業はドメイン取得の都合上、割愛しています。
※もしも独自ドメイン割当てをしたい場合はサポートメンバーに言ってください！！

<p>　</p>
***