[JAWS-UG CLI] S3:#12 オリジナルCDP Website Hosting

CDPを意識したハンズオンを行います。

# ハンズオンの対象となるCDP(案)

https://github.com/JAWS-UG-ARCH/AWS-CDP-Hybrid/issues/21


ハイレベルS3コマンドを利用して、S3上で静的Webホスティングを構築します。

前提条件
========


S3への権限
----------

* S3に対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

* AWS CLI 1.10.1


```bash:コマンド:
aws --version
```

```text:結果(例):
aws-cli/1.10.1 Python/2.7.5 Darwin/13.4.0 botocore/1.3.23
```

0.1. リージョンの決定
---------------------

作成するS3バケットのリージョンを決めます。

(カレントユーザが利用するカレントリージョンも切り変わります。)

```bash:コマンド(東京リージョンの場合):
export AWS_DEFAULT_REGION='ap-northeast-1'
```



0.2. 変数の確認
---------------

プロファイルとリージョンが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       s3Full-prjZ-mbp13iamFull-prjZ-mbp13              env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region           ap-northeast-1              env    AWS_DEFAULT_REGION
```

AssumeRoleを利用している場合はprofileが '\<not set\>'と表示されます。
それ以外のときにprofileが '\<not set\>'  と表示される場合は、以下を実行してください。

```bash:コマンド:
export AWS_DEFAULT_PROFILE=<IAMユーザ名>
```

1. 事前作業
===========

1.1. 組織名/プロジェクト名の決定
--------------------------------

S3バケット名を決めます。
(英小文字と数字が使えます。S3上でユニークである必要があります。英大文字は使用できません。)

ここでは、組織名-プロジェクト名-handsonという名前のバケットを利用するものとします。


```bash:コマンド:
ORG_NAME=<組織名>
PRJ_NAME=<プロジェクト名>
```

```bash:コマンド(例):
S3_BUCKET_NAME="${ORG_NAME}-handson-$(date +%Y%m%d%H%M)" \
  && echo ${S3_BUCKET_NAME}
```


1.2. 同名バケットの不存在確認
-----------------------------

```bash:コマンド:
aws s3 ls s3://${S3_BUCKET_NAME}/
```

```text:結果:
A client error (NoSuchBucket) occurred when calling the ListObjects operation: The specified bucket does not exist
```



# 2. バケットの作成 (mb)

コンテンツ公開用のS3バケットを作成します。

```bash:変数の確認:コマンド:
cat << ETX

  S3_BUCKET_NAME: ${S3_BUCKET_NAME}

ETX
```

バケットを作成します。

```bash:コマンド:
aws s3 mb s3://${S3_BUCKET_NAME}
```

```text:結果(例):
make_bucket: s3://example-handson-20151008/
```

# 3. websiteホスティングの設定 (website)

コンテンツ公開用のS3バケットのwebsiteホスティング設定を行ないます。

```bash:変数の確認:
cat << ETX

        S3_BUCKET_NAME: ${S3_BUCKET_NAME}

ETX
```

```bash:コマンド:
aws s3 website "s3://${S3_BUCKET_NAME}" \
  --index-document index.html \
  --error-document error.html
```

```text:結果:
(返り値なし)
```


# 4. コンテンツ用バケットのポリシー設定

S3で公開している静的コンテンツについて、バケット単位でのポリシー設定を行ないます。

これにより、#3まででは新規ファイルをアップロードするたびに個別設定が必要だったACL指定が不要になります。

(実際にはバケットポリシーとACLは組み合わせて使うものですが。)



## 4.1. 設定ファイルの作成

```bash:変数の設定:
FILE_S3_BUCKET_POLICY='s3-policy-readonly.json'
```

```bash:変数の確認:
cat << ETX

  FILE_S3_BUCKET_POLICY: ${FILE_S3_BUCKET_POLICY}
  S3_BUCKET_NAME: ${S3_BUCKET_NAME}

ETX
```

```bash:コマンド
cat << EOF > ${FILE_S3_BUCKET_POLICY}
{
  "Version":"2012-10-17",
  "Statement":[{
      "Sid":"AddPerm",
      "Effect":"Allow",
        "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::${S3_BUCKET_NAME}/*"]
    }
  ]
}
EOF

cat ${FILE_S3_BUCKET_POLICY}
```

```json:s3-policy-readonly.json:
{
  "Version":"2012-10-17",
  "Statement":[{
      "Sid":"AddPerm",
      "Effect":"Allow",
        "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::example-handson-201602011830/*"]
    }
  ]
}
```

JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。

```bash:コマンド:
jsonlint -q ${FILE_S3_BUCKET_POLICY}
```

```text:result:
(戻り値なし)
```

## 4.2. ポリシーの適用

```bash:変数の確認:
cat << ETX

  S3_BUCKET_NAME:        ${S3_BUCKET_NAME}
  FILE_S3_BUCKET_POLICY: ${FILE_S3_BUCKET_POLICY}

ETX
```

```bash:コマンド:
aws s3api put-bucket-policy \
  --bucket ${S3_BUCKET_NAME} \
  --policy file://${FILE_S3_BUCKET_POLICY}
```

```text:result:
(戻り値なし)
```


## 4.3. ポリシーの確認

```bash:コマンド:
aws s3api get-bucket-policy \
  --bucket ${S3_BUCKET_NAME}
```

```json:result:
{
    "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"AddPerm\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"s3:GetObject\",\"Resource\":\"arn:aws:s3:::example-handson-201602011830/*\"}]}"
}
```


# 5. コンテンツの転送 (sync)

## 5.1. コンテンツの用意 (任意)

(gitが使える場合)

```bash:コマンド:
git clone https://github.com/opelab/jawsug-cli-sample-web.git && cd jawsug-cli-sample-web
```

```text:結果:
      Cloning into 'jawsug-cli-sample-web'...
      remote: Counting objects: 5, done.
      remote: Total 5 (delta 0), reused 0 (delta 0), pack-reused 5
      Unpacking objects: 100% (5/5), done.
      Checking connectivity... done.
```


```bash:コマンド:
ls
```

```text:結果:
error.html  img.jpg         index.html
```

(gitが使えない場合)

http://jawsug-cli.s3-website-ap-northeast-1.amazonaws.com/jawsug-cli-sample-web.zip を取得して、解凍し、解凍後のディレクトリにcdコマンドで移動してください。



## 5.2. コンテンツの同期

クライアントPCに保存してあるサンプルコンテンツを、先程作成したコンテンツ公開用のS3バケットに同期します。

```bash:変数の確認:
cat << ETX

        S3_BUCKET_NAME: ${S3_BUCKET_NAME}

ETX
```

```bash:コマンド(gitの場合):
aws s3 sync . "s3://${S3_BUCKET_NAME}/" \
  --exclude ".git*"
```

```text:結果(例):
upload: ./error.html to s3://www.example.jp/error.html
upload: ./index.html to s3://www.example.jp/index.html
upload: ./img.jpg to s3://www.example.jp/img.jpg
```




# 6. アクセス確認

コンテンツ公開用のS3バケットがコンテンツ公開設定になっているか確認します。
この時点ではS3が自動的に付与するURLでアクセスします。

```bash:変数の確認:
cat << ETX

        AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
        S3_BUCKET_NAME: ${S3_BUCKET_NAME}

ETX
```

```bash:コマンド:
S3_BUCKET_ENDPOINT="${S3_BUCKET_NAME}.s3-website-`aws s3api get-bucket-location --bucket ${S3_BUCKET_NAME} --output text`.amazonaws.com" \
        && echo ${S3_BUCKET_ENDPOINT}
```


```text:結果(例):
example-handson-20151008.s3-website-ap-northeast-1.amazonaws.com
```

Webブラウザで EndPoint が開ければOKです。


# ログ設定

必要に応じて、バケットのログ設定をしましょう。

http://qiita.com/tcsh/items/b4c1c468e7bd54817f3f#5-%E3%83%AD%E3%82%B0%E8%A8%AD%E5%AE%9A%E3%81%AE%E4%BA%8B%E5%89%8D%E4%BD%9C%E6%A5%AD


# 完了