AWS初心者（一ヶ月）がサーバレス開発　～ S3 & Cloud Front編 ～

AWS を触り始めて一ヶ月の人間がサーバレス開発します。

# 経緯

社内で「 AWS の資格の勉強するんだったら、コレ作ってみてよ」と、渡されたモノがこちら。

|![capture_000020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/160490dc-51d7-3c84-a01a-676b0160f5eb.png)|
|:--|

|![capture_000021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/ce6c63c0-ecc1-2569-0a8e-68195bdbbe99.png)|
|:--|

ふんふん、なるほど、わからん。
仕様自体はシンプルなんだけど、AWS のサービスとかわからんちん。

「で、過程を Qiita に投稿してもらうから」

# 脳内作戦会議

AWS を触り始めて一ヶ月の僕には荷が重いわけで。
幸いなことに、サービスは指定されているわけで。
大雑把に、フロント側、バック側、その他の３つに分けて進めれば良いんじゃないかと思うに至ったわけで。

|![capture_000022.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/5cf19a63-7b64-8053-9374-51834f7ce531.png)|
|:--|

- 作業a : S3 & CloudFront (本記事)
- 作業b : API Gateway & Lambda & DynamoDB
- 作業c : CloudWatch と サービス間の接続周り 

# S3 & CloudFront

やりたいことはコレだ。

- 紙芝居でオッケーな HTML を S3 に配置
- S3 に配置した HTML を CloudFront 経由で公開

紙芝居な HTML をこんな感じで作成してみたりして。

```
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>抽選サイト</title>
    <link rel="icon" href="./favicon.ico">
    <link rel='stylesheet' href='./css/style.css'>
</head>

<body>
    <div class="main">
        <div class="header"> 
            <img src="./logo.png">
        </div>
        <div class="content">
            <h1>マスク抽選販売のお知らせ</h1>
            <br />
            <h3>抽選応募方法のご案内</h3>
            <br />
            <p>応募サイトにて、お名前/メールアドレス/電話番号をご入力ください。</p>
            <br />
            <button type="button" onclick="location.href='./entry.html'" class="btn-square">応募サイトはこちら</a>
        </div>
    </div>
</body>

</html>
```

## S3 で静的ウェブサイトホスティング

まず、S3 のみで静的ウェブサイトホスティングってのをやってみる。
やってみる、と言っても公式のハンズオンとチュートリアルをトレースするだけなんだけど。

キモの静的ウェブサイトホスティングの設定は枠で囲った３箇所だけ。

|![static-web-hosting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/7892f23b-7b6c-18a8-38b5-c4977ac8480e.png)|
|:--|

設定が終わると静的ウェブサイトホスティングのエリアが次のようになる。

|![static-web-hosting2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/7c823510-7bd0-8a47-14bb-1a929ae36b57.png)|
|:--|

表示されている URL をクリックして
![capture_000002_mask.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/a01a3f11-54c1-7c40-c45f-ba5ed5019aeb.png)
ぎゃー、でた。
念の為、存在しない URL を叩いてみる。
![capture_000005_mask.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/c3913e0c-2574-0cf4-46de-b3bcbbf48cf1.png)
静的ウェブサイトホスティングで設定したエラーページを表示してくれるのね。
メッセージが妥当でないことは目を伏せるとして。

自前で Apache をこねくり回していた若き日のソレは遠い過去ですな。


## CloudFront 経由でアクセス

公式のハンズオンとチュートリアルのトレースに勤しむ。

設定はというと枠で囲った４箇所のみ。

|![cf_create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/f4158501-2de3-1923-a551-3d46a856b32c.png)|
|:--|

ほどなくCloudFront と S3 の紐付けが完了。

|![cf_created.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/ed80b906-5442-ba02-8eae-c68cf6699973.png)|
|:--|

Domain Name にある URL を叩くと
![capture_000004_mask.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/e3c3cf55-606a-f26e-58ed-622582608060.png)
あっさりと、でた。
ところが存在しない URL を叩くと予想外の XML 形式のレスポンスが目に映る。
![capture_000008_mask.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/02c473c2-4ae7-b6bb-4588-6c7ce4492382.png)
CloudFront 側でエラーレスポンス動作を設定しておかないとコレらしい。
HTTP エラーコードが 404 じゃなくて 403 なのが引っかかるけど。
Web の集合知によれば、S3 と CloudFront はこういうものらしい。
理解が追いつかないので思考停止気味に CloudFront の Error Pages の設定を開いて、

|![capture_000011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/c097c233-567f-460b-8e16-b0a5aa663bc7.png)|
|:--|

静的なサイトだから 403 と 404 で十分だろう、と設定を追加してみると、 
![capture_000009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/a794b694-ccc6-d09b-6a24-4d427a20173c.png)
いえす、でた。
ふんふん、でも、この時点では S3 への直接アクセスも可能なのよね。
CloudFront 経由でのみアクセスできるようにしたいのよね。

### OAI による制限

OAI(Origin Access Identity)というのがあるらしい。
CloudFront で  OAI を設定すると、S3 へのアクセスを CloudFront 経由のみに制限できるらしい。
らしいのだが、実は前段で OAI は既に設定済みなわけで。
らしいのだが、S3 に直接アクセスもできちゃっているわけで。
理解が追いつかないまま現実逃避しようとしていたら、OAI の設定に関する公式の資料中にこんな記述があったわけで。

> 注: この設定では、バケットで静的ウェブサイトホスティングを有効にする必要はありません。この設定では、静的ウェブサイトホスティング機能のウェブサイトエンドポイントではなく、バケットの REST API エンドポイントを使用します。

つまり、静的ウェブサイトホスティングは不要だったわけで。

ところで、S3 で静的ウェブサイトホスティングを有効にすると「ウェブサイトエンドポイント」ってのが次の形式で作られる。

> - ***s3-website ダッシュ (-) リージョン*** ‐ http://<font color="red">*bucket-name*</font>.s3-website-<font color="red">*Region*</font>.amazonaws.com
> - ***s3-website ドット (.) リージョン*** ‐ http://<font color="red">*bucket-name*</font>.s3-website.<font color="red">*Region*</font>.amazonaws.com

いま、S3 への直接アクセスに利用しているのは、この URL だ。
理解が追いついた。
S3 で静的ウェブサイトホスティングを無効化すれば、この URL は使えなくなるはず。

|![s3.console.aws.amazon.com_s3_home_region=ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/9df2227b-ee8a-4b58-1375-d32120d8a851.png)|
|:--|

使えなくなったはずの URL を叩いてみると、

![capture_000014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164835/b949ed1a-638c-0aaa-d3a6-dfa152732a42.png)

おーいえす。

こっちは 404 だな。

ということで今回の目的は達した。

株式会社メソドロジック
三嶋　圭　@k-mishima

# 参考
- [チュートリアル: Amazon S3 での静的ウェブサイトの設定 - Amazon Simple Storage Service](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html)
- [CloudFront を使用して Amazon S3 でホストされた静的ウェブサイトを公開する](https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudfront-serve-static-website/)
- [エラーレスポンス動作を構成する - Amazon CloudFront](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/custom-error-pages-procedure.html)
- [オブジェクトとカスタムエラーページを別の場所に格納する - Amazon CloudFront](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/custom-error-pages-cache-behavior.html)
- [CloudFront 経由で S3 のファイルにアクセスする - Qiita](https://qiita.com/NaokiIshimura/items/46994e67b712831c3016)