【AWS】S3で静的WEBサイトホスティングを使ってWEBページを公開する

#はじめに
S3とはSimple Storage Serviceの略で、その名の通りファイルをアップロードして保存することができるストレージサービスです。
しかしS3は単なるストレージサービスではなく、HTMLファイルをアップロードして簡単なWEBページを作成することができます。

#簡単な用語の説明
・バケット……オブジェクトを格納するためのコンテナのこと。いわゆる頂点となるフォルダ。
・オブジェクト……S3バケットに格納されるデータのこと。ファイルなど。

#用意するもの
次のHTMLファイル

```index.html
<!DOCTYPE html>
<html>
　<head>
　　<meta charset="UTF-8">
　</head>
　<body>
　　This is Test Page!
　</body>
</html>
```

#手順
S3のコンソールを開きます。`バケットを作成`をクリックします。
![S3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/d60d1e12-c933-f34c-554e-3b4a868ae1dd.png)
バケット名はグローバルに一意である必要があります。つまり他のどんなS3バケットと名前が被ってはいけません。
リージョンは`アジアパシフィック(東京)`を選択します。
今回は外部に向けてWEBページを公開したいので「パブリックアクセスのブロック」はオフにします。
他の設定はデフォルトのままでバケットを作成します。
![S3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/3da49953-5be5-f69d-5997-ab561c1658fa.png)
バケットが作成されたのでバケットを開きます。
オブジェクトをアップロードします。
![S3_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/089db8b3-6545-1af7-771e-12f1f22dc693.png)
`ファイルを追加`で用意したindex.htmlをアップロードします。
![S3_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/084a766e-276b-606a-b1ac-743dee98f4fb.png)
アップロードが成功しました。
![S3_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/45ee3580-7db3-7f1b-d302-f4f2efc6ceef.png)
バケットのプロパティを開きます。
![S3_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/b93bdcab-4bb5-1b32-fd48-cab1d09127c7.png)
下へスクロールして静的ウェブサイトホスティングを編集します。
![S3_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/a2168561-7664-3e15-4d11-d55351345469.png)
静的ウェブサイトホスティングを有効にします。
インデックスドキュメントは「index.html」とします。
`変更の保存`をクリックします
![S3_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/6e7a68ac-bb23-e28b-5b66-32c955164a0a.png)
これだけではまだブラウザから目的のページにアクセスできません。
試しにオブジェクトのURLからアクセスしてみます。
![S3_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/3ad718ff-e2bb-1e3c-01f6-2c53b8bf0960.png)
このようなエラーが返されます。これはS3バケットの権限が足りていないため生じるエラーです。
![S3_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/dadb56f3-d73b-251b-8669-dd5ee019b12e.png)
バケットの`アクセス許可`を開きます。
![S3_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/96e7bce5-004b-2951-21a2-cb7e9a82811a.png)
下へスクロールし、バケットポリシーを編集します。
![S3_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/84d00e68-28f4-8ede-b828-e692396f7bd4.png)
画像のようにポリシーを記述します。
![S3_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/0bd13bc5-234d-a1f0-7684-2e3d35210943.png)
このJSONテキストは[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/WebsiteAccessPermissionsReqd.html)から参照可能です。
`xxxxxxxx`の部分がバケット名です。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::xxxxxxxx/*"
            ]
        }
    ]
}
```

各項目を簡単に見て行きましょう。
`Version`は「ポリシーを処理するために使用される言語構文ルール」を指定します。`2012-10-17`が現行バージョンです。
`Statement`はポリシーの主要な要素です。
`Sid`はステートメントIDの略で、ポリシーの任意の識別子です。
`Effect`はステートメントの結果を許可するか拒否するかを指定します。許可する場合は`Allow`、拒否する場合は`Deny`です。
`Principal`は「リソースへのアクセスを許可または拒否するユーザー、アカウント、サービス」などを指定します。`*`はワイルドカードで、誰でもアクセスできることを意味します。
`Action`は対象（リソース）に対して許可または拒否したいアクションを指定します。`GetObject`はS3からオブジェクトを取得できるアクションです。その他アクションは[こちら（英語版公式ドキュメント）](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/API/API_Operations.html)。
`Resource`はバケットやオブジェクトなどのARN（Amazon Resource Name）を指定します。バケットのARNの後ろに`/*`と追記してあげることでバケットに格納されているオブジェクトすべてを指定しているわけです。

さて、WEBページを公開する準備は整いました。
オブジェクトURLからページを開いてみましょう。
![S3_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844185/d7a81ca0-e9be-521a-7672-119a302d1f36.png)
無事に表示されました。

#参考

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/WebsiteHosting.html

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/access-policy-language-overview.html

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements.html

---
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com