Help us understand the problem. What is going on with this article?

[JAWS-UG CLI] STS:#3 AssumeRole

More than 5 years have passed since last update.

AWS CLIを利用して、AssumeRoleを利用します。

前提条件

EC2、S3、IAM、STSへの権限

  • EC2、S3、IAM、STSに対してフル権限があること。

AWS CLIのバージョン

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

  • AWS CLI 1.7.39
コマンド
aws --version
結果(例)
aws-cli/1.7.39 Python/2.7.6 Darwin/14.4.0

0. 準備

0.1. リージョンの指定

リージョンを指定しておきます。

コマンド
export AWS_DEFAULT_REGION=ap-northeast-1

0.2. 変数の確認

プロファイルが想定のものになっていることを確認します。(EC2/S3/IAM/STSフル権限が必要です。)

コマンド
aws configure list
結果(例)
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                  iamFull           manual    --profile
access_key     ****************IK5Q shared-credentials-file    
secret_key     ****************nA0/ shared-credentials-file    
    region           ap-northeast-1              env    AWS_DEFAULT_REGION

0.3. 作業用ディレクトリの確認

カレントディレクトリにファイルを出力する為、作業用のディレクトリをご用意ください。

コマンド
pwd
ls -l

1. 事前準備

1.1. AWS IDの取得

ここで、AWS_IDを取得しておきます。

コマンド
AWS_ID=`aws iam get-user \
  --query 'User.Arn' \
  --output text | sed 's/^.*:://' | sed 's/:.*$//'` \
  && echo ${AWS_ID}
結果(例)
123456789012

1.2. AssumeRoleするIAMユーザの作成

作成予定のIAMユーザが存在しないことを確認します。

変数の設定
IAM_USER_NAME=AssumeRoleUser
コマンド
aws iam get-user \
  --user-name ${IAM_USER_NAME}
結果(例)
A client error (NoSuchEntity) occurred when calling the GetUser operation: The user with name AssumeRoleUser cannot be found.

IAMユーザを作成します。

コマンド
aws iam create-user \
  --user-name ${IAM_USER_NAME}
結果(例)
{
    "User": {
        "UserName": "AssumeRoleUser", 
        "Path": "/", 
        "CreateDate": "2015-07-18T12:20:05.016Z", 
        "UserId": "AIDAIPV37O2FG3D2FLUAA", 
        "Arn": "arn:aws:iam::123456789012:user/AssumeRoleUser"
    }
}

1.3. IAMユーザに割り当てるポリシーの作成

AssumeRoleするIAMユーザに割り当てるポリシーを準備します。

変数の設定
IAM_USER_POLICY_NAME=${IAM_USER_NAME}_Policy \
  && echo ${IAM_USER_POLICY_NAME}

FILE_IAM_USER_POLICY=${IAM_USER_POLICY_NAME}.json \
  && echo ${FILE_IAM_USER_POLICY}

AssumeRoleするIAMユーザには、AssumeRoleする権限とEC2へのフルアクセスのみを付与します。

コマンド
cat << EOF > ${FILE_IAM_USER_POLICY}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "ec2:*",
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": "sts:AssumeRole",
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}
EOF

cat ${FILE_IAM_USER_POLICY}

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

コマンド
jsonlint -q ${FILE_IAM_USER_POLICY}

作成予定のIAMポリシーが存在しないことを確認します。

コマンド
aws iam get-policy \
  --policy-arn arn:aws:iam::${AWS_ID}:policy/${IAM_USER_POLICY_NAME}
結果(例)
A client error (NoSuchEntity) occurred when calling the GetPolicy operation: Policy arn:aws:iam::123456789012:policy/AssumeRoleUser_Policy does not exist.

IAMポリシーを作成します。

コマンド
aws iam create-policy \
  --policy-name ${IAM_USER_POLICY_NAME} \
  --policy-document file://./${FILE_IAM_USER_POLICY}
結果(例)
{
    "Policy": {
        "PolicyName": "AssumeRoleUser_Policy", 
        "CreateDate": "2015-07-18T12:32:57.113Z", 
        "AttachmentCount": 0, 
        "IsAttachable": true, 
        "PolicyId": "ANPAIWXOFZB7YS2ZLY7FW", 
        "DefaultVersionId": "v1", 
        "Path": "/", 
        "Arn": "arn:aws:iam::123456789012:policy/AssumeRoleUser_Policy", 
        "UpdateDate": "2015-07-18T12:32:57.113Z"
    }
}

作成したポリシーのARNを取得します。

コマンド
IAM_USER_POLICY_ARN=$(aws iam list-policies \
  --scope Local \
  --query "Policies[?PolicyName==\`${IAM_USER_POLICY_NAME}\`].Arn[]" \
  --output text) \
  && echo ${IAM_USER_POLICY_ARN}

1.4. ポリシーのIAMユーザへの割り当て

作成したポリシーをIAMユーザに割り当てます。

コマンド
aws iam attach-user-policy \
  --user-name ${IAM_USER_NAME} \
  --policy-arn ${IAM_USER_POLICY_ARN}
結果(例)
(戻り値なし)

設定したIAMユーザとそのポリシーを確認します。

コマンド
aws iam get-account-authorization-details \
    --filter User \
    --query "UserDetailList[?UserName==\`${IAM_USER_NAME}\`]"
結果(例)
[
    {
        "UserName": "AssumeRoleUser", 
        "GroupList": [], 
        "CreateDate": "2015-07-18T12:20:05Z", 
        "UserId": "AIDAIPV37O2FG3D2FLUAA", 
        "Path": "/", 
        "AttachedManagedPolicies": [
            {
                "PolicyName": "AssumeRoleUser_Policy", 
                "PolicyArn": "arn:aws:iam::123456789012:policy/AssumeRoleUser_Policy"
            }
        ], 
        "Arn": "arn:aws:iam::123456789012:user/AssumeRoleUser"
    }
]
コマンド
aws iam get-account-authorization-details \
    --filter LocalManagedPolicy \
    --query "Policies[?PolicyName==\`${IAM_USER_POLICY_NAME}\`]"
結果(例)
[
    {
        "PolicyName": "AssumeRoleUser_Policy", 
        "CreateDate": "2015-07-18T12:32:57Z", 
        "AttachmentCount": 1, 
        "IsAttachable": true, 
        "PolicyId": "ANPAIWXOFZB7YS2ZLY7FW", 
        "DefaultVersionId": "v1", 
        "PolicyVersionList": [
            {
                "CreateDate": "2015-07-18T12:32:57Z", 
                "VersionId": "v1", 
                "Document": {
                    "Version": "2012-10-17", 
                    "Statement": [
                        {
                            "Action": "ec2:*", 
                            "Resource": "*", 
                            "Effect": "Allow"
                        }, 
                        {
                            "Action": "sts:AssumeRole", 
                            "Resource": "*", 
                            "Effect": "Allow"
                        }
                    ]
                }, 
                "IsDefaultVersion": true
            }
        ], 
        "Path": "/", 
        "Arn": "arn:aws:iam::123456789012:policy/AssumeRoleUser_Policy", 
        "UpdateDate": "2015-07-18T12:32:57Z"
    }
]

1.5. AssumeRoleされるIAMロールの作成

クロスアカウント環境を用意するのは難しいと思いますので、今回は同一AWSアカウント内でAssumeRoleします。
IAMロールのTrusted Entitiy(IAMロール利用を許可する対象)を定義しておきます。
先に作成したIAMユーザからのみAssumeRoleを許可します。

変数の設定
FILE_ASSUME_ROLE_POLICY=assume-role-policy.json
コマンド
cat << EOF > ${FILE_ASSUME_ROLE_POLICY}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Principal": {
                "AWS": "arn:aws:iam::${AWS_ID}:user/${IAM_USER_NAME}"
            }
        }
    ]
}
EOF

cat ${FILE_ASSUME_ROLE_POLICY}

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

コマンド
jsonlint -q ${FILE_ASSUME_ROLE_POLICY}

作成予定のIAMロールが存在しないことを確認します。

変数の設定
IAM_ROLE_NAME=AssumedRole
コマンド
aws iam get-role \
  --role-name=${IAM_ROLE_NAME}
結果(例)
A client error (NoSuchEntity) occurred when calling the GetRole operation: The role with name AssumedRole cannot be found.

IAMロールを作成します。

コマンド
aws iam create-role \
  --role-name ${IAM_ROLE_NAME} \
  --assume-role-policy-document file://./${FILE_ASSUME_ROLE_POLICY}  
結果(例)
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17", 
            "Statement": [
                {
                    "Action": "sts:AssumeRole", 
                    "Effect": "Allow", 
                    "Principal": {
                        "AWS": "arn:aws:iam::123456789012:user/AssumeRoleUser"
                    }
                }
            ]
        }, 
        "RoleId": "AROAIYJKSO3BOXIHFYL7S", 
        "CreateDate": "2015-07-18T13:18:11.938Z", 
        "RoleName": "AssumedRole", 
        "Path": "/", 
        "Arn": "arn:aws:iam::123456789012:role/AssumedRole"
    }
}

1.6. IAMロールに割り当てるポリシーの作成

IAMロールに割り当てるポリシーを準備します。

変数の設定
IAM_ROLE_POLICY_NAME=${IAM_ROLE_NAME}_Policy
FILE_IAM_ROLE_POLICY=${IAM_ROLE_POLICY_NAME}.json

AssumeRoleするIAMユーザには、AssumeRoleする権限とEC2へのフルアクセスのみを付与します。

コマンド
cat << EOF > ${FILE_IAM_ROLE_POLICY}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*"
        }
    ]
}
EOF

cat ${FILE_IAM_ROLE_POLICY}

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

コマンド
jsonlint -q ${FILE_IAM_ROLE_POLICY}

作成予定のIAMポリシーが存在しないことを確認します。

コマンド
aws iam get-policy \
  --policy-arn arn:aws:iam::${AWS_ID}:policy/${IAM_ROLE_POLICY_NAME}
結果(例)
A client error (NoSuchEntity) occurred when calling the GetPolicy operation: Policy arn:aws:iam::123456789012:policy/AssumedRole_Policy does not exist.

IAMポリシーを作成します。

コマンド
aws iam create-policy \
  --policy-name ${IAM_ROLE_POLICY_NAME} \
  --policy-document file://./${FILE_IAM_ROLE_POLICY}
結果(例)
{
    "Policy": {
        "PolicyName": "AssumedRole_Policy", 
        "CreateDate": "2015-07-18T13:21:24.728Z", 
        "AttachmentCount": 0, 
        "IsAttachable": true, 
        "PolicyId": "ANPAI3CYOIQ6J2SAC3I3E", 
        "DefaultVersionId": "v1", 
        "Path": "/", 
        "Arn": "arn:aws:iam::123456789012:policy/AssumedRole_Policy", 
        "UpdateDate": "2015-07-18T13:21:24.728Z"
    }
}

作成したポリシーのARNを取得します。

コマンド
IAM_ROLE_POLICY_ARN=$(aws iam list-policies \
  --scope Local \
  --query "Policies[?PolicyName==\`${IAM_ROLE_POLICY_NAME}\`].Arn[]" \
  --output text) \
  && echo ${IAM_ROLE_POLICY_ARN}

1.7. ポリシーのIAMロールへの割り当て

作成したポリシーをIAMロールに割り当てます。

コマンド
aws iam attach-role-policy \
  --role-name ${IAM_ROLE_NAME} \
  --policy-arn ${IAM_ROLE_POLICY_ARN}
結果(例)
(戻り値なし)

設定したIAMロールとそのポリシーを確認します。

コマンド
aws iam get-account-authorization-details \
    --filter Role \
    --query "RoleDetailList[?RoleName==\`${IAM_ROLE_NAME}\`]"
結果(例)
[
    {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17", 
            "Statement": [
                {
                    "Action": "sts:AssumeRole", 
                    "Principal": {
                        "AWS": "arn:aws:iam::123456789012:user/AssumeRoleUser"
                    }, 
                    "Effect": "Allow", 
                    "Sid": ""
                }
            ]
        }, 
        "RoleId": "AROAIYJKSO3BOXIHFYL7S", 
        "CreateDate": "2015-07-18T13:18:11Z", 
        "InstanceProfileList": [], 
        "RoleName": "AssumedRole", 
        "Path": "/", 
        "AttachedManagedPolicies": [
            {
                "PolicyName": "AssumedRole_Policy", 
                "PolicyArn": "arn:aws:iam::123456789012:policy/AssumedRole_Policy"
            }
        ], 
        "RolePolicyList": [], 
        "Arn": "arn:aws:iam::123456789012:role/AssumedRole"
    }
]
コマンド
aws iam get-account-authorization-details \
    --filter LocalManagedPolicy \
    --query "Policies[?PolicyName==\`${IAM_ROLE_POLICY_NAME}\`]"
結果(例)
[
    {
        "PolicyName": "AssumedRole_Policy", 
        "CreateDate": "2015-07-18T13:21:24Z", 
        "AttachmentCount": 1, 
        "IsAttachable": true, 
        "PolicyId": "ANPAI3CYOIQ6J2SAC3I3E", 
        "DefaultVersionId": "v1", 
        "PolicyVersionList": [
            {
                "CreateDate": "2015-07-18T13:21:24Z", 
                "VersionId": "v1", 
                "Document": {
                    "Version": "2012-10-17", 
                    "Statement": [
                        {
                            "Action": "s3:*", 
                            "Resource": "*", 
                            "Effect": "Allow"
                        }
                    ]
                }, 
                "IsDefaultVersion": true
            }
        ], 
        "Path": "/", 
        "Arn": "arn:aws:iam::123456789012:policy/AssumedRole_Policy", 
        "UpdateDate": "2015-07-18T13:21:24Z"
    }
]

2. AssumeRole利用

2.1. IAMユーザのアクセスキー発行

AssumeRoleするIAMユーザのアクセスキーを発行しておきます。

変数の設定
FILE_IAM_USER_ACCEESS_KEY=${IAM_USER_NAME}_AccessKey.json
コマンド
aws iam create-access-key \
  --user-name ${IAM_USER_NAME} \
  > ${FILE_IAM_USER_ACCEESS_KEY} &&
  cat ${FILE_IAM_USER_ACCEESS_KEY}
結果(例)
{
    "AccessKey": {
        "UserName": "AssumeRoleUser", 
        "Status": "Active", 
        "CreateDate": "2015-07-18T13:33:14.757Z", 
        "SecretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "AccessKeyId": "AKIAxxxxxxxxxxxxxxxx"
    }
}

2.2. Configファイル準備

IAMユーザのアクセスキーをConfigファイルに設定します。

変数の設定
PROFILE_IAM_USER=assume-user
FILE_PROFILE_IAM_USER_CONFIG=${PROFILE_IAM_USER}.config
コマンド
echo "[profile ${PROFILE_IAM_USER}]" > ${FILE_PROFILE_IAM_USER_CONFIG}
cat ${FILE_IAM_USER_ACCEESS_KEY} | awk '
  $1 == "\"AccessKeyId\":" {
    gsub(/\"/,""); gsub(/,/,""); print "aws_access_key_id = "$2
  }
  $1 == "\"SecretAccessKey\":" {
    gsub(/\"/,""); gsub(/,/,""); print "aws_secret_access_key = "$2
  }
' >> ${FILE_PROFILE_IAM_USER_CONFIG} \
  && cat ${FILE_PROFILE_IAM_USER_CONFIG}

ここでAssumeRoleする為のプロファイルも追記しておきます。

変数の設定
PROFILE_IAM_ROLE=assumed-role
コマンド
echo "[profile ${PROFILE_IAM_ROLE}]" >> ${FILE_PROFILE_IAM_USER_CONFIG}
echo "role_arn = arn:aws:iam::${AWS_ID}:role/${IAM_ROLE_NAME}" >> ${FILE_PROFILE_IAM_USER_CONFIG}
echo "source_profile = ${PROFILE_IAM_USER}" >> ${FILE_PROFILE_IAM_USER_CONFIG}

作成したファイルの内容を確認しておきましょう。

コマンド
cat ${FILE_PROFILE_IAM_USER_CONFIG}
結果(例)
[profile assume-user]
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
aws_access_key_id = AKIAxxxxxxxxxxxxxxxx
[profile assumed-role]
role_arn = arn:aws:iam::123456789012:role/AssumedRole
source_profile = assume-user

2.3. AssumeRoleするIAMユーザでの動作確認

作成したConfigファイルをプロファイルとして環境変数で設定します。

環境変数指定
export AWS_DEFAULT_PROFILE=${PROFILE_IAM_USER}
export AWS_CONFIG_FILE=${FILE_PROFILE_IAM_USER_CONFIG}

AssumeRoleするIAMユーザ用のプロファイルに変更されていることを確認します。

コマンド
aws configure list
結果(例)
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile              assume-user           manual    --profile
access_key     ****************BPKQ      config-file    
secret_key     ****************tgBm      config-file    
    region           ap-northeast-1              env    AWS_DEFAULT_REGION

AssumeRoleするIAMユーザでは、EC2にアクセス可能、S3にアクセス不可であることを確認しておきます。

コマンド(例)
aws ec2 describe-regions
コマンド(例)
aws s3 ls

2.4. ConfigファイルによるAssumeRoleの利用

AssumeRoleしたプロファイルで同様のコマンド結果を確認します。
正しく設定できていれば、先程とは逆の結果になるはずです。

コマンド(失敗例)
aws ec2 describe-regions --profile ${PROFILE_IAM_ROLE}
コマンド(成功例)
aws s3 ls --profile ${PROFILE_IAM_ROLE}

2.5. 手動でのAssumeRoleの利用

念の為、手動でもAssumeRoleを利用できることを確認します。
Tokenの有効期限を15分(60*15)に設定します。

変数の設定
EXPIRATION_SECONDS=`expr 60 \* 15`
FILE_ASSUME_ROLE_OUTPUT=assume_role_output.json
ROLE_SESSION_NAME=assumed-role-session
IAM_ROLE_ARN=arn:aws:iam::${AWS_ID}:role/${IAM_ROLE_NAME}

AssumeRoleTokenを取得します。

変数の確認
cat << ETX

        IAM_ROLE_ARN: ${IAM_ROLE_ARN}
        ROLE_SESSION_NAME: ${ROLE_SESSION_NAME}
        EXPIRATION_SECONDS: ${EXPIRATION_SECONDS}
        FILE_ASSUME_ROLE_OUTPUT: ${FILE_ASSUME_ROLE_OUTPUT}

ETX
コマンド
aws sts assume-role \
  --role-arn ${IAM_ROLE_ARN} \
  --role-session-name ${ROLE_SESSION_NAME} \
  --duration-seconds ${EXPIRATION_SECONDS} \
  > ${FILE_ASSUME_ROLE_OUTPUT} \
  && cat ${FILE_ASSUME_ROLE_OUTPUT}    

ここでは環境変数を利用してAssumeRoleTokenを利用します。

変数の設定
FILE_ASSUME_ROLE_ENV=assume_role.env
コマンド
cat ${FILE_ASSUME_ROLE_OUTPUT} | awk '
    $1 == "\"AccessKeyId\":" {
      gsub(/\"/,""); gsub(/,/,""); print "export AWS_ACCESS_KEY_ID="$2
    }
    $1 == "\"SecretAccessKey\":" {
      gsub(/\"/,""); gsub(/,/,""); print "export AWS_SECRET_ACCESS_KEY="$2
    }
    $1 == "\"SessionToken\":" {
      gsub(/\"/,""); gsub(/,/,""); print "export AWS_SESSION_TOKEN="$2
    }
' > ${FILE_ASSUME_ROLE_ENV} \
  && cat ${FILE_ASSUME_ROLE_ENV}

unset AWS_DEFAULT_PROFILE
source ${FILE_ASSUME_ROLE_ENV}

手動で取得したAssumeRoleTokenでも、Configファイル利用の場合と同様に、EC2にアクセス不可、S3にアクセス可能であることを確認します。

コマンド(失敗例)
aws ec2 describe-regions
コマンド(成功例)
aws s3 ls

3. 作成リソースの削除

3.1. 環境変数等の初期化

必要に応じて環境変数の削除、再設定を行って、作業開始時(管理者)の権限に初期化(または再設定)してください。
プロファイルが想定のものになっていることを確認します。

コマンド
aws configure list
結果(例)
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                  iamFull           manual    --profile
access_key     ****************IK5Q shared-credentials-file    
secret_key     ****************nA0/ shared-credentials-file    
    region           ap-northeast-1              env    AWS_DEFAULT_REGION

3.2. IAMユーザの削除

IAMユーザとそれに紐付くリソースを全て削除します。

変数の設定
IAM_USER_NAME=AssumeRoleUser
IAM_USER_POLICY_NAME=${IAM_USER_NAME}_Policy
IAM_USER_POLICY_ARN=$(aws iam list-policies \
  --scope Local \
  --query "Policies[?PolicyName==\`${IAM_USER_POLICY_NAME}\`].Arn[]" \
  --output text)
ACCESS_KEY_ID=$(aws iam list-access-keys \
  --user-name ${IAM_USER_NAME} \
  --query "AccessKeyMetadata[].AccessKeyId[]" \
  --output text)
コマンド
aws iam detach-user-policy \
  --user-name ${IAM_USER_NAME} \
  --policy-arn ${IAM_USER_POLICY_ARN}
コマンド
aws iam delete-policy \
  --policy-arn ${IAM_USER_POLICY_ARN}
コマンド
aws iam delete-access-key \
  --access-key-id ${ACCESS_KEY_ID} \
  --user-name ${IAM_USER_NAME}
コマンド
aws iam delete-user \
  --user-name ${IAM_USER_NAME}

3.3. IAMロールの削除

IAMロールとそれに紐付くリソースを全て削除します。

変数の設定
IAM_ROLE_NAME=AssumedRole
IAM_ROLE_POLICY_NAME=${IAM_ROLE_NAME}_Policy
IAM_ROLE_POLICY_ARN=$(aws iam list-policies \
  --scope Local \
  --query "Policies[?PolicyName==\`${IAM_ROLE_POLICY_NAME}\`].Arn[]" \
  --output text)
コマンド
aws iam detach-role-policy \
  --role-name ${IAM_ROLE_NAME} \
  --policy-arn ${IAM_ROLE_POLICY_ARN}
コマンド
aws iam delete-policy \
  --policy-arn ${IAM_ROLE_POLICY_ARN}
コマンド
aws iam delete-role --role-name ${IAM_ROLE_NAME}

3.4. 作業用ファイルの削除

念の為、不要となったカレントディレクトリのローカルファイルも削除してください。

完了

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away