【AWS】S3 静的ウェブサイトホスティング

# 目的
S3を使って簡単なWEBページを即時インターネット公開する。

## 手順の流れ
- S3バケットを作成する

公開したいWEBサイトのHTMLファイル等を格納するバケットを作成する。
バケット名はURLに含まれる。

http://<b><バケット名></b>.s3-website-<リージョン名>.amazonaws.com

バケット名は世界で一意となる名前でなければならない。

- バケットに公開する資材（HTMLファイル等）を格納する
- バケットのアクセス権を設定する
- 静的ウェブサイトホスティングを有効にする

## コンソールから作成
S3サービス画面から「バケットを作成」をクリックする。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/c80ad743-b060-3d08-4830-a31d00a8d1e4.png">

任意のリージョン及びバケット名を指定する。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/73bc99de-fe34-4f58-b746-214f6ddf656b.png">

「パブリックアクセスをすべて ブロック」
のチェックを外し、警告の承認にチェックする。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/f98ecf1c-4fe0-f8c4-dfce-8f15e7025538.png">

「バケットを作成」をクリックし作成する。

公開するHTMLファイルを格納する。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/a04d66cd-0331-0ddf-7ad4-0328c9972584.png">

タブ「アクセス許可」の「バケットポリシー」セクションを編集して、以下を設定する。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/a250629c-ac66-3e08-99ac-5bd6cea353b2.png">
```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Principal": "*",
			"Effect": "Allow",
			"Action": [
				"s3:GetObject"
			],
			"Resource": "arn:aws:s3:::<バケット名>/*"
		}
	]
}
```
タブ「プロパティ」の「静的ウェブサイトホスティング」セクションを編集する。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/e6a6e28d-ad53-41a8-689a-488183bef9fd.png">
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/d8c1a59c-f43f-a238-d303-c7f0fb796e46.png">

「有効にする」及びインデックスドキュメント名（先ほど配置したHTMLファイル名）を指定して、変更を保存する。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/d0750091-c329-72a9-c74e-d018f33dc622.png">

すると、「静的ウェブサイトホスティング」セクションにURLが表示されるのでアクセス確認する。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/c4e61d96-540e-e3fe-836e-e134684966b6.png">

HTTPでの接続となる。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/2f9ead98-13c2-45b7-843a-ca7adf622056.png">

## AWSCLIで作成
同様のことをAWSCLIを使用してやってみる。
※AWSCLIが使用できる環境が整っている前提。
環境はWindows11PCのPowershell。

### バケットの作成
```powershell
aws s3api create-bucket --bucket <バケット名> --create-bucket-configuration LocationConstraint=<リージョン名>
```
| コマンド/オプション | 説明 |
|:--|:--|
| s3api | S3の操作を行うためのコマンドセット  |
| create-bucket  | 新しいS3バケットを作成する  |
|--bucket|バケットの名前を指定する|
|--create-bucket-configuration LocationConstraint|バケットを作成するリージョン|

実行例
```powershell
> aws s3api create-bucket --bucket asl-demo-awscli --create-bucket-configuration LocationConstraint=ap-northeast-1
{
    "Location": "http://asl-demo-awscli.s3.amazonaws.com/"
}
```

### バケットに公開する資材（HTMLファイル等）を格納する

```powershell
aws s3 cp <HTMLファイルなどが格納されているローカルのPATH> s3://<バケット名>/
```
実行例
```powershell
> aws s3 cp C:\Users\user1\Desktop\index.html s3://asl-demo-awscli/
upload: .\index.html to s3://asl-demo-awscli/index.html
```
### バケットのアクセス権を設定する

#### パブリックアクセスブロックの無効化
```powershell
aws s3api put-public-access-block --bucket <バケット名> `
--public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"
```

#### バケットポリシーの作成
ちょっと見ずらいが、ダブルクォートをエスケープする必要がある。
```powershell
> aws s3api put-bucket-policy --bucket <バケット名> --policy `
>> '{\"Version\": \"2012-10-17\",
>>   \"Statement\": [
>>     {
>>       \"Effect\": \"Allow\",
>>       \"Principal\": \"*\",
>>       \"Action\": \"s3:GetObject\",
>>       \"Resource\": \"arn:aws:s3:::<バケット名>/*\"
>>     }
>>   ]
>> }'
```
### 静的ウェブサイトホスティングを有効にする
```powershell
> aws s3api put-bucket-website --bucket asl-demo-awscli --website-configuration `
>> '{
>>   \"IndexDocument\": {
>>     \"Suffix\": \"index.html\"
>>   }
>> }'
```
### 動作確認
http://<b><バケット名></b>.s3-website-<リージョン名>.amazonaws.com
にアクセスして公開状況を確認します。

実行例　※curlでもブラウザでもお好きな方法で
```powershell
> Invoke-WebRequest -Uri "http://asl-demo-awscli.s3-website-ap-northeast-1.amazonaws.com"

StatusCode        : 200
StatusDescription : OK
・・・続く
```
## CloudFormationで作成
上記をCFのテンプレートにすると以下のようになる。
※このケースではHTMLファイルの格納のみCloudFormation実行後に手動となる。
```yaml:s3create.yaml
AWSTemplateFormatVersion: "2010-09-09"
Resources:
    S3Bucket:
        Type: "AWS::S3::Bucket"
        Properties:
            BucketName: "asl-demo-cf"
            BucketEncryption: 
                ServerSideEncryptionConfiguration: 
                  - 
                    ServerSideEncryptionByDefault: 
                        SSEAlgorithm: "AES256"
                    BucketKeyEnabled: false
            WebsiteConfiguration: 
                IndexDocument: "index.html"
            OwnershipControls: 
                Rules: 
                  - 
                    ObjectOwnership: "BucketOwnerEnforced"
            PublicAccessBlockConfiguration: 
                BlockPublicAcls: false
                BlockPublicPolicy: false
                IgnorePublicAcls: false
                RestrictPublicBuckets: false

    S3BucketPolicy:
        Type: "AWS::S3::BucketPolicy"
        Properties:
            Bucket: !Ref S3Bucket
            PolicyDocument: 
                Version: "2012-10-17"
                Statement: 
                  - 
                    Effect: "Allow"
                    Principal: "*"
                    Action: "s3:GetObject"
                    Resource: !Sub "arn:aws:s3:::${S3Bucket}/*"
```

このYAMLファイルを使ってコンソールからスタックを作成してもいいし、AWSCLIでコマンド実行してもよい。

AWSCLIを使用する場合の実行例
```powershell
> aws cloudformation create-stack --stack-name s3websitehosting --template-body file://s3create.yaml
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:<AWSアカウント>:stack/s3websitehosting/2cd1e820-c57a-11ee-b0c7-0621c375615d"
}
```
スタックのステータスが「CREATE_COMPLETE」となったら、作成されたバケットにHTMLファイルをアップロードして動作確認を実施する。

コンソールの場合
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348322/b0670fd7-e5c0-cee3-f0a0-c4b38f948c7d.png">

AWSCLIの場合
```powershell
> aws cloudformation describe-stacks --stack-name s3websitehosting --query 'Stacks[0].StackStatus' --output json
"CREATE_COMPLETE"
```

# 最後に
公開したいWEBページの資材が出来上がっていて、セキュリティもドメインもアクセス負荷も特段要件が無いならば、おそらく3分もあれば公開完了する。

非公開にするのも一瞬で出来るので、本当に一時的な商用PRページとかお知らせレベルのサイトであれば使えるか・・・？