[JAWS-UG CLI] IAM # S3 put用IAMロール


AWS CLIを利用して、S3 put用のIAMロールの作成をしてみます。


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


Cognito (Identity)への権限
-------------------

* Cognito (Identity)に対してフル権限があること。


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

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

  * AWS CLI 1.8.3

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

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


0. 準備
=======


0.1. 変数の確認
---------------

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

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

```text:結果(例):

            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       iamFull-prjZ-mbp13iamFull-prjZ-mbp13              env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region                eu-west-1              env    AWS_DEFAULT_REGION
```


0.2. Cognito ID Pool IDの指定
-----------------------------

```bash:変数の設定(例):
COGNITO_IDPOOL_ID='ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
```


0.3. S3バケット名の指定
-----------------------

```bash:変数の設定(例):
S3_BUCKET_NAME=<バケット名>
```


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


1.1. IAMロール名の決定
----------------------

```bash:変数の設定:
IAM_ROLE_NAME='Cognito_s3putUnauth_Role'
```

同じ名前のIAMロールが存在しないことを確認します。

```bash:コマンド:
aws iam get-role \
         --role-name ${IAM_ROLE_NAME}
```

```text:結果(例):
      A client error (NoSuchEntity) occurred when calling the GetRole operation: The role with name ecsInstanceRole cannot be found.
```


1.2. assumeロールポリシドキュメントの作成
-----------------------------------------

```bash:変数の設定:
FILE_ROLE_DOC="${IAM_ROLE_NAME}.json" \
        && echo ${FILE_ROLE_DOC}
```

```bash:コマンド:
cat << EOF >> ${FILE_ROLE_DOC}
{
        "Version": "2008-10-17",
        "Statement": [
          {
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Principal": {
              "Federated": "cognito-identity.amazonaws.com"
            },
            "Effect": "Allow",
            "Condition": {
              "StringEquals": {
                "cognito-identity.amazonaws.com:aud": "${COGNITO_IDPOOL_ID}"
              },
              "ForAnyValue:StringLike": {
                "cognito-identity.amazonaws.com:amr": "unauthenticated"
              }
            },
            "Sid": ""
          }
        ]
}
EOF

cat ${FILE_ROLE_DOC}
```

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

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


2. IAMロールの作成
==================


2.1. IAMロールの作成
--------------------

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

        IAM_ROLE_NAME: ${IAM_ROLE_NAME}
        FILE_ROLE_DOC: ${FILE_ROLE_DOC}

ETX
```

```bash:コマンド:
aws iam create-role \
        --role-name ${IAM_ROLE_NAME} \
        --assume-role-policy-document file://${FILE_ROLE_DOC}
```

```json:結果(例):

      {
        "Role": {
          "AssumeRolePolicyDocument": {
              "Version": "2008-10-17",
              "Statement": [
                  {
                      "Action": "sts:AssumeRoleWithWebIdentity",
                      "Sid": "",
                      "Effect": "Allow",
                      "Condition": {
                          "StringEquals": {
                              "cognito-identity.amazonaws.com:aud": "ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
                          },
                          "ForAnyValue:StringLike": {
                              "cognito-identity.amazonaws.com:amr": "unauthenticated"
                          }
                      },
                      "Principal": {
                          "Federated": "cognito-identity.amazonaws.com"
                      }
                  }
              ]
          },
          "RoleId": "AROAXXXXXXXXXXXXXXXXX",
          "CreateDate": "2015-09-28T08:12:38.002Z",
          "RoleName": "Cognito_s3putUnauth_Role",
          "Path": "/",
          "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/Cognito_s3putUnauth_Role"
        }
      }
```


2.2. IAMロールの確認
--------------------

```bash:コマンド:
aws iam get-role \
         --role-name ${IAM_ROLE_NAME}
```


3. ロールポリシ (cognito-sync)
==============================


3.1. IAMロールポリシーの作成
----------------------------

```bash:変数の設定:
IAM_ROLE_POLICY_NAME='oneClick_Cognito_s3putUnauth_Role'
FILE_ROLE_POLICY_DOC="${IAM_ROLE_POLICY_NAME}.json" \
        && echo ${FILE_ROLE_POLICY_DOC}
```

```bash:コマンド:
cat << EOF > ${FILE_ROLE_POLICY_DOC}
{
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "mobileanalytics:PutEvents",
              "cognito-sync:*"
            ],
            "Resource": [
              "*"
            ]
          }
        ]
}
EOF

cat ${FILE_ROLE_POLICY_DOC}
```

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

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


3.2. ロールポリシーの適用
-------------------------

ロールポリシーをIAMロールに適用します。

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

        IAM_ROLE_NAME:        ${IAM_ROLE_NAME}
        IAM_ROLE_POLICY_NAME: ${IAM_ROLE_POLICY_NAME}
        FILE_ROLE_POLICY_DOC: ${FILE_ROLE_POLICY_DOC}

ETX
```

```bash:変数の確認:
aws iam put-role-policy \
        --role-name ${IAM_ROLE_NAME} \
        --policy-name ${IAM_ROLE_POLICY_NAME} \
        --policy-document file://${FILE_ROLE_POLICY_DOC}
```


4. ロールポリシ (s3put)
=======================


4.1. IAMロールポリシーの作成
----------------------------

```bash:変数の設定:
IAM_ROLE_POLICY_NAME='s3put'
FILE_ROLE_POLICY_DOC="${IAM_ROLE_POLICY_NAME}.json" \
        && echo ${FILE_ROLE_POLICY_DOC}
```

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

cat ${FILE_ROLE_POLICY_DOC}
```

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

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


4.2. ロールポリシーの適用
-------------------------

ロールポリシーをIAMロールに適用します。

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

        IAM_ROLE_NAME:        ${IAM_ROLE_NAME}
        IAM_ROLE_POLICY_NAME: ${IAM_ROLE_POLICY_NAME}
        FILE_ROLE_POLICY_DOC: ${FILE_ROLE_POLICY_DOC}

ETX
```

```bash:変数の確認:
aws iam put-role-policy \
        --role-name ${IAM_ROLE_NAME} \
        --policy-name ${IAM_ROLE_POLICY_NAME} \
        --policy-document file://${FILE_ROLE_POLICY_DOC}
```


5. 事後作業
===========


5.1. IAMロールの確認
--------------------

```bash:コマンド:
aws iam get-role \
         --role-name ${IAM_ROLE_NAME}
```

```json:結果(例):
      {
              "AssumeRolePolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                      {
                          "Action": "sts:AssumeRoleWithWebIdentity",
                          "Principal": {
                              "Federated": "cognito-identity.amazonaws.com"
                          },
                          "Effect": "Allow",
                          "Condition": {
                              "StringEquals": {
                                  "cognito-identity.amazonaws.com:aud": "us-east-1:48b8f559-9c64-40e3-b38f-9860fc0240df"
                              },
                              "ForAnyValue:StringLike": {
                                  "cognito-identity.amazonaws.com:amr": "unauthenticated"
                              }
                          },
                          "Sid": ""
                      }
                  ]
              },
              "RoleId": "AROAI24WZFOE4TPB4D46A",
              "CreateDate": "2015-09-14T21:57:57Z",
              "RoleName": "Cognito_s3putUnauth_Role",
              "Path": "/",
              "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/Cognito_s3putUnauth_Role"
      }
```


5.2. ロールポリシの確認
-----------------------

```bash:コマンド:
aws iam list-role-policies   --role-name ${IAM_ROLE_NAME}
```

```json:結果:
      {
        "PolicyNames": [
          "oneClick_Cognito_s3putUnauth_Role",
          "s3put"
        ]
      }
```

```bash:コマンド:
IAM_ROLE_POLICY_NAME='oneClick_Cognito_s3putUnauth_Role'
```

```bash:コマンド:
aws iam get-role-policy \
        --role-name ${IAM_ROLE_NAME} \
        --policy-name ${IAM_ROLE_POLICY_NAME}
```

```json:結果(例):
      aws iam get-role-policy \
      {
        "RoleName": "Cognito_s3putUnauth_Role",
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Action": [
                      "mobileanalytics:PutEvents",
                      "cognito-sync:*"
                  ],
                  "Resource": [
                      "*"
                  ],
                  "Effect": "Allow"
              }
          ]
        },
        "PolicyName": "oneClick_Cognito_s3putUnauth_Role"
      }
```

```bash:コマンド:
IAM_ROLE_POLICY_NAME='s3put'
```

```bash:コマンド:
aws iam get-role-policy \
        --role-name ${IAM_ROLE_NAME} \
        --policy-name ${IAM_ROLE_POLICY_NAME}
```

```json:結果(例):
      {
        "RoleName": "Cognito_s3putUnauth_Role",
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Action": [
                      "s3:PutObject",
                      "s3:PutObjectAcl"
                  ],
                  "Resource": "arn:aws:s3:::example/*",
                  "Effect": "Allow",
                  "Sid": ""
              }
          ]
        },
        "PolicyName": "s3put"
      }
```

マネジメントコンソール上は、"信頼関係"に cognito-identity.amazonaws.com が表示されています。


## 5.3. IAMロールのARN

```bash:コマンド:
IAM_ROLE_ARN=$( \
  aws iam get-role \
    --role-name ${IAM_ROLE_NAME} \
    --query 'Role.Arn' \
    --output text \
) \
  && echo ${IAM_ROLE_ARN}
```


## 5.4. 

```bash:コマンド:
aws cognito-identity set-identity-pool-roles \
  --identity-pool-id ${COGNITO_IDPOOL_ID} \
  --roles unauthenticated=${IAM_ROLE_ARN}
```


```bash:コマンド:
aws cognito-identity get-identity-pool-roles \
  --identity-pool-id ${COGNITO_IDPOOL_ID} 
```

```json:結果(例):
{
    "IdentityPoolId": "ap-northeast-1:f08b5f56-4132-4762-ab95-4188346e4b8b", 
    "Roles": {
        "unauthenticated": "arn:aws:iam::XXXXXXXXXXXX:role/Cognito_s3putUnauth_Role"
    }
}
```


完了
====