S3+CloudFrontで静的サイトを配信する

## S3を静的サイトとして配信したい

AWSで簡単なペラページとかをサクッと公開したいときとかの手順です。

公式の通りにやればいいんですが、HTTP Onlyらしいです。

[静的ウェブサイトホスティング用に S3 バケットを設定する方法](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/static-website-hosting.html)

なので、S3のウェブサイトホスティングは使わずにS3+CloudFrontで設定してみます。

## S3作成

### バケットを作成

設定はデフォルトで大丈夫です。
index.htmlでも入れておきましょう。

## CloudFront作成

### Distribute作成

Distributionを作成します。

### Origin Settings

#### OriginにS3を設定

Origin DOmain Nameに先程作成したバケットを指定します。
ボックスにフォーカスするとリストで出てきますのでそのまま選んで大丈夫です。
`<BucketName>.s3.amazonaws.com`となります。
Origin IDは自動で入力されるのでそのままで。

#### Restrict Bucket Accessを設定

Yesを選択することで、CloudFrontからのアクセスを許可できます。

#### Origin Access Identity

Create a New Identityで専用のIAMが作られます。
なお、ひとつ作ればそれを使い回すことも可能です。

#### Comment

`access-identity-s3-access`としました。

#### Grant Read Permissions on Bucket

Yesにすると、S3のバケットポリシーに自動で書き込まれます。

ということで、Origin Settingsはこんな感じになりました。

<img width="1059" alt="Screen Shot 2018-11-01 at 20.09.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/31268/cc822096-32c4-d69d-77a6-f3f7528101b3.png">

### Default Cache Behavior Settings

#### Viewer Protocol Policy

`Redirect HTTP to HTTPS`を選択すればHTTPSにリダイレクトするようになります。

<img width="747" alt="Screen Shot 2018-11-01 at 20.13.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/31268/0bef30c8-37f3-ce8f-5278-e45ef91daaa0.png">

#### Compress Objects Automatically

`Compress Objects Automatically`をYesにすることで、gzip圧縮をかけられます。

<img width="699" alt="Screen Shot 2018-06-03 at 23.15.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/31268/e9dee123-f58c-4fed-d794-0a21d832795c.png">

### Distribution Settings

#### Default Root Object

`Default Root Object`に`index.html`を指定するとドメインのみのアクセスでindex.htmlが表示されるようになります。

<img width="832" alt="Screen Shot 2018-06-03 at 22.30.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/31268/a2dc32c7-032a-a3da-9d85-8e77b0fb7e5b.png">

### 保存

保存して15分ぐらい待つとデプロイが完了して、CloudFrontのドメインにアクセス可能になります。

### その他

#### 404ページ

存在しないページを表示するとS3のエラーレスポンスがXMLで表示されてしまいます。

<img width="789" alt="Screen Shot 2018-11-01 at 21.01.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/31268/eb6a0754-ec1b-937b-f783-05931de12879.png">

こちらはCloudFrontの`Error Pages`設定で変更可能です。
エラーレスポンスが403となってますので、404に書き換えてあげます。

<img width="694" alt="Screen Shot 2018-11-01 at 21.04.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/31268/0aa12b2d-4b02-2f90-d956-8c6af19a769f.png">

なお、S3から403じゃなくて404で返してほしい場合はS3のバケットポリシーにs3:ListBucketのActionを追加すれば404になります。

#### SPA

SPAをルーティングで動かすにはちょっとした設定が必要です。

<img width="714" alt="Screen Shot 2018-11-13 at 18.36.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/31268/460dc993-188b-8b20-c30b-2b71f034bb89.png">

`/foo`でアクセスした場合、ファイルがないため403が返されますが、そこをindex.htmlを返すように変えてあげればオッケーです。

#### CORS

CORSを有効にするには、S3とCloudFrontの設定が必要となります。

##### S3

アクセス権限 -> CORSの設定に下記を適応します。

```
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
```

##### CloudFront

Behaivorの設定でWhitelist Headersに下記を設定します。

<img width="836" alt="Screen Shot 2018-11-13 at 18.40.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/31268/4fca3f77-7751-7f99-f17c-d78c838bc58f.png">