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. 作業用ファイルの削除
念の為、不要となったカレントディレクトリのローカルファイルも削除してください。
#完了