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

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

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

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


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


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

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


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

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

* AWS CLI 1.10.11

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

```bash:結果(例):

      aws-cli/1.10.4 Python/2.7.5 Darwin/13.4.0 botocore/1.3.26
```


0. 準備
=======


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

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

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

```bash:変数の設定:
export AWS_DEFAULT_REGION='ap-northeast-1'
```


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

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

```bash:コマンド:
aws configure list
```

```bash:結果(例)

            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile         s3Full-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. バケット名の決定

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

        S3_BUCKET_NAME:    ${S3_BUCKET_NAME}
        S3_BUCKET_LOG:     ${S3_BUCKET_LOG}

ETX
```


ログバケットを作成したときの変数が有効な場合は、以下の変数を宣言しておきます。

```bash:変数の設定:
S3_BUCKET_LOG="${S3_BUCKET_NAME}"
S3_BUCKET_NAME="${S3_BUCKET_ORIGIN}"
```


変数が未設定の場合は、以下を設定します。

```bash:変数の設定:
ORG_NAME=<組織名>
PRJ_NAME='handson'
```

注釈: (英小文字と数字が使えます。S3上でユニークである必要があります。英大 文字は使用できません。)

```bash:変数の設定:
S3_BUCKET_NAME="${ORG_NAME}-${PRJ_NAME}-$(date +%Y%m%d%H)" \
        && echo ${S3_BUCKET_NAME}
```


## 1.2. 確認

同名バケットが存在しないことを確認します。

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

```bash:結果(例):

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




2. バケットの作成
=================

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

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

ETX
```

```bash:コマンド:
aws s3api create-bucket \
        --bucket ${S3_BUCKET_NAME} \
        --create-bucket-configuration "LocationConstraint=${AWS_DEFAULT_REGION}"
```

```json:結果(例):

      {
        "Location": "http://corp-handson-20160309.s3.amazonaws.com/"
      }
```

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

```json:結果(例):

      {
        "LocationConstraint": "ap-northeast-1"
      }
```


3. バケットポリシーの設定
=========================


3.1. 設定ファイルの作成
-----------------------

```bash:変数の設定
FILE_S3_BUCKET_POLICY="s3-policy-readonly-${S3_BUCKET_NAME}.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ファイルを作成したら、フォーマットが壊れてないか必ず確認します。

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

```bash:結果:
(戻り値なし)
```


3.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}
```

```bash:結果:

      (戻り値なし)
```


3.3. ポリシーの確認
-------------------

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

```json:結果(例):

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


4. コンテンツの転送、確認
=========================


4.1. コンテンツの用意 (任意)
----------------------------

gitが使える場合

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

```bash:結果(例):

      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
```

```bash:結果:

      error.html  img.jpg         index.html
```

gitが使えない場合

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


4.2. コンテンツの同期
---------------------

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

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

        S3_BUCKET_NAME: ${S3_BUCKET_NAME}

ETX
```

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

```bash:結果(例):

      upload: ./error.html to s3://corp-handson-20160309/error.html
      upload: ./index.html to s3://corp-handson-20160309/index.html
      upload: ./img.jpg to s3://corp-handson-20160309/img.jpg
```


4.3. アクセス確認
-----------------

コンテンツ公開用のS3バケットがコンテンツ公開設定になっているか確認します。

```bash:変数の設定:
TARGET_OBJECT='img.jpg'
```

```bash:変数の確認:
URL_S3_BUCKET="http://s3-${AWS_DEFAULT_REGION}.amazonaws.com/${S3_BUCKET_NAME}/${TARGET_OBJECT}" \
        && echo ${URL_S3_BUCKET}
```

```bash:結果(例)

      http://s3-ap-northeast-1.amazonaws.com/corp-handson-20160309/img.jpg
```



5. ログ設定の事前作業
===========


5.1. ログ用バケット名の存在確認
---------------------------

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

```bash:結果(例)
(戻り値なし)
```

エラーが表示されなければOKです。



5.2. AWSアカウント ログイン用メールアドレスの指定
-------------------------------------------------

```bash:変数の設定:
MAIL_ACCOUNT=<AWSアカウント ログイン用メールアドレス>
```


5.3. ログ用プレフィクスの指定
-----------------------------

```bash:変数の設定:
S3_PREFIX_LOG=Logs
```


設定ファイルの作成
------------------

```bash:変数の設定
FILE_INPUT="s3-bucket-logging-${S3_BUCKET_NAME}.json"
```

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

        FILE_INPUT:    ${FILE_INPUT}
        S3_BUCKET_LOG: ${S3_BUCKET_LOG}
        S3_PREFIX_LOG: ${S3_PREFIX_LOG}
        MAIL_ACCOUNT:  ${MAIL_ACCOUNT}

ETX
```

```bash:コマンド:
cat << EOF > ${FILE_INPUT}
{
        "LoggingEnabled": {
          "TargetBucket": "${S3_BUCKET_LOG}",
          "TargetPrefix": "${S3_PREFIX_LOG}/",
          "TargetGrants": [
            {
              "Grantee": {
                "Type": "AmazonCustomerByEmail",
                "EmailAddress": "${MAIL_ACCOUNT}"
              },
              "Permission": "FULL_CONTROL"
            },
            {
              "Grantee": {
                "Type": "Group",
                "URI": "http://acs.amazonaws.com/groups/global/AllUsers"
              },
              "Permission": "READ"
            }
          ]
        }
}
EOF

cat ${FILE_INPUT}
```

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

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

エラーが出力されなければOKです。


6. ログ設定
===========

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

        S3_BUCKET_NAME: ${S3_BUCKET_NAME}
        FILE_S3_LOGGING: ${FILE_S3_LOGGING}

ETX
```

```bash:コマンド:
aws s3api put-bucket-logging \
        --bucket ${S3_BUCKET_NAME} \
        --bucket-logging-status file://${FILE_INPUT}
```

```bash:結果:
(戻り値なし)
```


7. ログ設定の事後作業
===========


7.1. ログ設定の確認
-------------------

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

```json:結果(例):

      {
        "LoggingEnabled": {
          "TargetPrefix": "Logs//",
          "TargetBucket": "accesslog-corp-handson-20160309",
          "TargetGrants": [
              {
                  "Grantee": {
                      "Type": "CanonicalUser",
                      "DisplayName": "corp",
                      "ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
                  },
                  "Permission": "FULL_CONTROL"
              },
              {
                  "Grantee": {
                      "Type": "Group",
                      "URI": "http://acs.amazonaws.com/groups/global/AllUsers"
                  },
                  "Permission": "READ"
              }
          ]
        }
      }
```


7.2. コンテンツにアクセスする
-----------------------------

Webブラウザで、コンテンツにアクセスしてみましょう。

```bash:変数の確認:
URL_S3_BUCKET="http://s3-${AWS_DEFAULT_REGION}.amazonaws.com/${S3_BUCKET_NAME}/${TARGET_OBJECT}" \
        && echo ${URL_S3_BUCKET}
```

```bash:結果(例)

      http://s3-ap-northeast-1.amazonaws.com/corp-handson-20160309/img.jpg
```

Webブラウザで EndPoint が開くと、アクセスログが書き込まれます。


7.3. ログ保存の確認
-------------------

30分から1時間ほど待つと、15分前までのログが書き出されているはずです。

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

```bash:結果(例):

      PRE Logs/
```

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

```bash:結果(例):

      2016-03-10 18:23:27        290 2014-08-24-09-23-26-XXXXXXXXXXXXXXXX
      2016-03-10 18:24:12        292 2014-08-24-09-24-11-YYYYYYYYYYYYYYYY
```


ログはベストエフォート設計のため、全てのアクセスが記録される保証は無いようです。
     http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html


完了
====