[JAWS-UG CLI] IAM Managed Policy:#17-1 作業用IAMユーザの作成

https://jawsug-cli.doorkeeper.jp/events/21038 でのハンズオン資料です。

AWS CLIを利用して、IAMへの限定的なアクセスが可能なIAMグループとIAMユーザを作成します。
（Inline Policyを使って設定を行います。#1以降で設定するManaged Policyとの違いを確認してみてください。）

なお、本日のハンズオンではこの手順の実施は必須です。
（この手順で作成するIAMグループに対してManaged PolicyをAttach/Dettachします。）

# 前提条件

## IAMへの権限

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

## AWS CLIのバージョン

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

```bash:command
aws --version
```

```text:result
aws-cli/1.7.22 Python/2.7.9 Linux/3.14.35-28.38.amzn1.x86_64
```

# 0. 事前準備

## リージョンの決定

作成するユーザのデフォルトリージョンを決めます。

```bash:commnad
export AWS_DEFAULT_REGION='ap-northeast-1'
```

## 変数の確認

現在有効なアクセスキーを確認します。
（結果例はIAM Roleを設定したEC2インスタンス上で実行した場合の例です。）

```bash:command
aws configure list
```

```text:result
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************PQVQ         iam-role
secret_key     ****************BoxI         iam-role
    region           ap-northeast-1              env    AWS_DEFAULT_REGION
```

# 1. 事前作業

## 1.1. 組織名、プロジェクト名、Pathの決定

```bash:command
PRJ_NAME="JAWSUG_CLI_17"
LOC_NAME="Coedo"
PATH_NAME="/jawsug-cli/"
```

## 1.2. IAMグループの決定

```bash:commnad
IAM_GROUP_NAME="IAM_limited"
```

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

```bash:command
aws iam get-group --group-name ${IAM_GROUP_NAME}
```

```text:result
A client error (NoSuchEntity) occurred when calling the GetGroup operation: The group with name IAM_limited cannot be found.
```

## 1.3. IAMグループポリシーの作成

ポリシー名を決めます。

```bash:command
IAM_GPOLICY_NAME="${IAM_GROUP_NAME}-${PRJ_NAME}"
echo ${IAM_GPOLICY_NAME}
```

```text:result
IAM_limited-JAWSUG_CLI_17
```

ポリシーファイルのファイル名を決めます。

```bash:command
FILE_POLICY_DOC="${IAM_GPOLICY_NAME}.json"
echo ${FILE_POLICY_DOC}
```

```text:result
IAM_limited-JAWSUG_CLI_17.json
```

AWSアカウントIDを指定します。

```bash:commnad
AWS_ACCOUNT_ID="************"
```

ポリシーファイルを作成します。

```bash:command
cat << EOF > ${FILE_POLICY_DOC}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:Create*",
                "iam:Delete*",
                "iam:Get*",
                "iam:List*",
                "iam:Set*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iam:Attach*",
                "iam:Detach*"
            ],
            "Condition": {
                "ArnEquals": {
                    "iam:PolicyArn": [
                        "arn:aws:iam::${AWS_ACCOUNT_ID}:policy${PATH_NAME}*",
                        "arn:aws:iam::aws:policy/AmazonS3FullAccess",
                        "arn:aws:iam::aws:policy/AmazonEC2ReportsAccess",
                        "arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess"
                    ]
                }
            },
            "Resource": [
                "arn:aws:iam::${AWS_ACCOUNT_ID}:group${PATH_NAME}*"
            ]
        }
    ]
}
EOF
```

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

```bash:commnad
jsonlint -q ${FILE_POLICY_DOC}
```

```text:result
（戻り値なし）
```

## 1.4. IAMユーザの決定

```bash:command
IAM_USER_NAME="${IAM_GROUP_NAME}-${PRJ_NAME}-${LOC_NAME}"
echo ${IAM_USER_NAME}
```

```text:commnad
IAM_limited-JAWSUG_CLI_17-Coedo
```

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

```bash:command
aws iam get-user --user-name ${IAM_USER_NAME}
```

```text:result
A client error (NoSuchEntity) occurred when calling the GetUser operation: The user with name IAM_limited-JAWSUG_CLI_17-Coedo cannot be found.
```

# 2. グループの作成

## 2.1. IAMグループの作成

```bash:commnad
cat << ETX
            IAM_GROUP_NAME: ${IAM_GROUP_NAME}
ETX
```

```text:result
            IAM_GROUP_NAME: IAM_limited
```

IAMグループを作成します。
（#1以降で、このIAMグループに対してManaged PolicyをAttachします。）

```bash:commnad
aws iam create-group --group-name ${IAM_GROUP_NAME} --path ${PATH_NAME}
```

```text:result
{
    "Group": {
        "Path": "/jawsug-cli/",
        "CreateDate": "2015-04-11T14:49:47.765Z",
        "GroupId": "A********************",
        "Arn": "arn:aws:iam::************:group/jawsug-cli/IAM_limited",
        "GroupName": "IAM_limited"
    }
}
```

## 2.2. IAMグループの確認

```bash:command
aws iam get-group --group-name ${IAM_GROUP_NAME}
```

```text:result
{
    "Group": {
        "Path": "/jawsug-cli/",
        "CreateDate": "2015-04-11T14:49:47Z",
        "GroupId": "A********************",
        "Arn": "arn:aws:iam::698675364418:group/jawsug-cli/IAM_limited",
        "GroupName": "IAM_limited"
    },
    "Users": []
}
```

# 3. グループポリシーの適用

## 3.1. IAMグループポリシーの適用

```bash:commnad
cat << ETX
        IAM_GROUP_NAME:   ${IAM_GROUP_NAME}
        IAM_GPOLICY_NAME: ${IAM_GPOLICY_NAME}
        FILE_POLICY_DOC:  ${FILE_POLICY_DOC}
ETX
```

```text:result
        IAM_GROUP_NAME:   IAM_limited
        IAM_GPOLICY_NAME: IAM_limited-JAWSUG_CLI_17
        FILE_POLICY_DOC:  IAM_limited-JAWSUG_CLI_17.json
```

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

```bash:commnad
aws iam put-group-policy \
        --group-name ${IAM_GROUP_NAME} \
        --policy-name ${IAM_GPOLICY_NAME} \
        --policy-document file://${FILE_POLICY_DOC}
```

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

## 3.2. IAMグループポリシーの確認

IAMグループのグループポリシーを確認します。

```bash:commnad
aws iam get-group-policy --group-name ${IAM_GROUP_NAME} --policy-name ${IAM_GPOLICY_NAME}
```

```text:result
{
    "GroupName": "IAM_limited",
    "PolicyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "iam:Create*",
                    "iam:Delete*",
                    "iam:Get*",
                    "iam:List*",
                    "iam:Set*"
                ],
                "Resource": [
                    "*"
                ],
                "Effect": "Allow"
            },
            {
                "Action": [
                    "iam:Attach*",
                    "iam:Detach*"
                ],
                "Resource": [
                    "arn:aws:iam::************:group/jawsug-cli/*"
                ],
                "Effect": "Allow",
                "Condition": {
                    "ArnEquals": {
                        "iam:PolicyArn": [
                            "arn:aws:iam::698675364418:policy/jawsug-cli/*",
                            "arn:aws:iam::aws:policy/AmazonS3FullAccess",
                            "arn:aws:iam::aws:policy/AmazonEC2ReportsAccess",
                            "arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess"
                        ]
                    }
                }
            }
        ]
    },
    "PolicyName": "IAM_limited-JAWSUG_CLI_17"
}
```

# 4. ユーザの作成

## 4.1. 作成

```bash:commnad
cat << ETX
        IAM_USER_NAME: ${IAM_USER_NAME}
ETX
```

```text:result
        IAM_USER_NAME: IAM_limited-JAWSUG_CLI_17-Coedo
```

IAMユーザを作成します。

```bash:command
aws iam create-user --user-name ${IAM_USER_NAME}
```

```text:result
{
    "User": {
        "UserName": "IAM_limited-JAWSUG_CLI_17-Coedo",
        "Path": "/",
        "CreateDate": "2015-04-11T15:04:18.109Z",
        "UserId": "A********************",
        "Arn": "arn:aws:iam::************:user/IAM_limited-JAWSUG_CLI_17-Coedo"
    }
}
```

## 4.2. IAMユーザの確認

作成したIAMユーザが存在することを確認します。

```bash:commnad
aws iam get-user --user-name ${IAM_USER_NAME}
```

```text:result
{
    "User": {
        "UserName": "IAM_limited-JAWSUG_CLI_17-Coedo",
        "Path": "/",
        "CreateDate": "2015-04-11T15:04:18Z",
        "UserId": "A********************",
        "Arn": "arn:aws:iam::************:user/IAM_limited-JAWSUG_CLI_17-Coedo"
    }
}
```

# 5. グループへのユーザ追加

## 5.1. 追加

```bash:commnad
cat << ETX
        IAM_GROUP_NAME: ${IAM_GROUP_NAME}
        IAM_USER_NAME:  ${IAM_USER_NAME}
ETX
```

```text:result
        IAM_GROUP_NAME: IAM_limited
        IAM_USER_NAME:  IAM_limited-JAWSUG_CLI_17-Coedo
```

IAMユーザに権限を付与するために、IAMグループに追加します。

```bash:commnad
aws iam add-user-to-group --group-name ${IAM_GROUP_NAME} --user-name ${IAM_USER_NAME}
```

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

## 5.2. ユーザのグループ所属確認

IAMユーザが、IAMグループに所属していることを確認します。

```bash:command
aws iam list-groups-for-user --user-name ${IAM_USER_NAME} |\
        jq -r --arg group_name ${IAM_GROUP_NAME} '.Groups[] | select( .GroupName == $group_name )'
```

```text:result
{
  "Path": "/jawsug-cli/",
  "CreateDate": "2015-04-11T14:49:47Z",
  "GroupId": "A********************",
  "Arn": "arn:aws:iam::************:group/jawsug-cli/IAM_limited",
  "GroupName": "IAM_limited"
}
```

## 5.3. グループへのユーザ所属確認

IAMグループにIAMユーザが所属していることを確認します。

```bash:commnad
aws iam get-group --group-name ${IAM_GROUP_NAME} |\
        jq -r --arg user_name ${IAM_USER_NAME} '.Users[] | select( .UserName == $user_name )'
```

```text:result
{
  "UserName": "IAM_limited-JAWSUG_CLI_17-Coedo",
  "Path": "/",
  "CreateDate": "2015-04-11T15:04:18Z",
  "UserId": "A********************",
  "Arn": "arn:aws:iam::************:user/IAM_limited-JAWSUG_CLI_17-Coedo"
}
```

# 6. ユーザのAPIアクセス設定

## 6.1. access keyの作成と取得

```bash:commnad
cat << ETX
        IAM_USER_NAME: ${IAM_USER_NAME}
ETX
```

```text:result
        IAM_USER_NAME: IAM_limited-JAWSUG_CLI_17-Coedo
```

```bash:commnad
aws iam create-access-key --user-name ${IAM_USER_NAME} > ${IAM_USER_NAME}.json \
        && cat ${IAM_USER_NAME}.json
```

```text:result
{
    "AccessKey": {
        "UserName": "IAM_flimited-JAWSUG_CLI_17-Coedo",
        "Status": "Active",
        "CreateDate": "2015-03-21T14:04:37.135Z",
        "SecretAccessKey": "****************************************",
        "AccessKeyId": "********************"
    }
}
```

## 6.2. 認証情報の作成

sourceディレクトリ作成

```bash:commnad
mkdir -p ~/.aws/source
```

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

rcファイル作成

```bash:commnad
cat ${IAM_USER_NAME}.json |\
        jq '.AccessKey | {AccessKeyId, SecretAccessKey}' |\
        sed '/[{}]/d' | sed 's/[\" ,]//g' | sed 's/:/=/' |\
        sed 's/AccessKeyId/aws_access_key_id/' |\
        sed 's/SecretAccessKey/aws_secret_access_key/' \
        > ~/.aws/source/${IAM_USER_NAME}.rc \
        && cat ~/.aws/source/${IAM_USER_NAME}.rc
```

```text:result
aws_access_key_id=********************
aws_secret_access_key=****************************************
```

configファイル(単体)作成

```bash:commnad
REGION_AWS_CONFIG='ap-northeast-1'
```

```bash:commnad
FILE_USER_CONFIG="${HOME}/.aws/source/${IAM_USER_NAME}.config"
echo "[profile ${IAM_USER_NAME}]" > ${FILE_USER_CONFIG} \
        && echo "region=${REGION_AWS_CONFIG}" >> ${FILE_USER_CONFIG} \
        && echo "" >> ${FILE_USER_CONFIG} \
        && cat ${FILE_USER_CONFIG}
```

```text:result
[profile IAM_limited-JAWSUG_CLI_17-Coedo]
region=ap-northeast-1
```

~/.aws/credentials作成

バックアップ

```bash:commnad
cp ~/.aws/credentials ~/.aws/credentials.old
```

```bash:commnad
file="${HOME}/.aws/credentials"
if [ -e ${file} ]; then mv ${file} ${file}.bak; fi
for i in `ls ${HOME}/.aws/source/*.rc`; do \
        name=`echo $i | sed 's/^.*\///' | sed 's/\.rc$//'` \
        && echo "[$name]" >> ${file} \
        && cat $i >> ${file} \
        && echo "" >> ${file} ;done \
        && cat ${file}
```

```text:result
[IAM_limited-JAWSUG_CLI_17-Coedo]
aws_access_key_id=********************
aws_secret_access_key=****************************************
```
~/.aws/config作成

```bash:commnad
cp ~/.aws/config ~/.aws/config.old
```

```bash:commnad
cat ${HOME}/.aws/source/*.config > ${HOME}/.aws/config \
        && cat ${HOME}/.aws/config
```

```text:result
[profile IAM_limited-JAWSUG_CLI_17-Coedo]
region=ap-northeast-1
```

# 7. ユーザの切り替え

## 7.1. 現在のユーザの確認

IAM Roleを利用している場合には、Profileはセットされていません。

```bash:commnad
aws configure list | grep profile
```

```text:result
   profile                <not set>             None    None
```

## 7.2. 切替後ユーザの確認

```bash:commnad
cat << ETX
        new:     IAM_USER_NAME:       ${IAM_USER_NAME}
ETX
```

```text:result
        new:     IAM_USER_NAME:       IAM_limited-JAWSUG_CLI_17-Coedo
```

## 7.3. ユーザの切り替え

```bash:commnad
export AWS_DEFAULT_PROFILE=${IAM_USER_NAME}
echo ${AWS_DEFAULT_PROFILE}
```

```text:result
IAM_limited-JAWSUG_CLI_17-Coedo
```

## 7.4. コマンドテスト

```bash:commnad
aws iam get-account-summary 
```

```text:result
{
    "SummaryMap": {
        "UsersQuota": 5000,
        "Policies": 2,
        "AttachedPoliciesPerGroupQuota": 2,
        "PoliciesQuota": 1000,
        "GroupsQuota": 100,
        "InstanceProfiles": 6,
        "SigningCertificatesPerUserQuota": 2,
        "ServerCertificatesQuota": 20,
        "RolesQuota": 250,
        "RolePolicySizeQuota": 10240,
        "AccountSigningCertificatesPresent": 0,
        "Users": 21,
        "PolicySizeQuota": 5120,
        "ServerCertificates": 0,
        "AssumeRolePolicySizeQuota": 2048,
        "Groups": 18,
        "MFADevicesInUse": 1,
        "PolicyVersionsInUseQuota": 10000,
        "VersionsPerPolicyQuota": 5,
        "AccountAccessKeysPresent": 0,
        "Roles": 10,
        "AccountMFAEnabled": 1,
        "MFADevices": 1,
        "GroupsPerUserQuota": 10,
        "GroupPolicySizeQuota": 5120,
        "InstanceProfilesQuota": 100,
        "AccessKeysPerUserQuota": 2,
        "AttachedPoliciesPerRoleQuota": 2,
        "PolicyVersionsInUse": 3,
        "Providers": 0,
        "AttachedPoliciesPerUserQuota": 2,
        "UserPolicySizeQuota": 2048
    }
}
```

# 8. 認証ファイルの削除

```bash:commnad
rm ${IAM_USER_NAME}.json
```

# 9. マネジメントコンソールへのアクセス許可 (任意)

ハンズオンで、マネジメントコンソールで動作確認すると理解が深まります。

# ハンズオン時

ハンズオン前にやっておくとよいこと(任意): http://qiita.com/tcsh/items/c905a2d8777db4282804

# ハンズオン後

ハンズオン実施後にやっておくべきこと(推奨): http://qiita.com/tcsh/items/dc966f6bd0380bda8905

# 完了

今回のハンズオンでは、このIAMユーザで実施することを前提とします。