aws-cli は ~/.aws/config
の profile に role_arn
を書いておけば、自動で assume-role してくれます。mfa_serial
を書けば MFA code にも対応。
これに対して AWS SDK for JavaScript はまだ ~/.aws/config
に非対応。~/.aws/credentials
しか見てくれないので、node 向けの管理ツールとかをさくっと作っても、assume-role が極めて面倒。
要は assume-role した後に出力される
- aws_access_key_id
- aws_secret_access_key
- aws_session_token
を ~/.aws/credentials
に書けば良い、ということなので、それを自動で行う shell script を。
使い方
最後に記載の script を適当に path が通っているところに mode 0775 で設置。
aws-assume-role -l
role_arn
を持つ profile のリストを出力します。
複数の profile を用意して様々な role に assume-role してると、profile 名を忘れてしまうので。。
aws-assume-role -p PROFILE
指定した profile に定義されている role に assume-role します。
mfa_serial
が定義されている場合には CLI と同様に Enter MFA code: と聞いてきますので、MFA デバイスで生成したコードを入力してください。
assume-role が成功すれば、set complete. と表示され、 ~/.aws/crefentials
の指定した profile 部分に一時的な aws_access_key_id
、aws_secret_access_key
、aws_session_token
が設定されます。
後は SDK で profile を指定すれば自動的に解釈してくれます。
aws-assume-role -p PROFILE -d SECONDS
-d SECONDS
を指定することで、(role 側で許可されていれば)duration を変更することができます。
デフォルトの duration は 3600(1時間)ですが、role の設定で最大 43200(12時間)まで拡大できます。
script file
#!/bin/bash
set -e
usage() {
echo "Usage: $0 [-lh] [-p profile] [-d duration_seconds]" 1>&2
exit 1
}
while getopts d:lp:h OPT; do
case $OPT in
d) duration=$OPTARG
;;
l) cmd='show'
;;
p) cmd='assume'
profile=$OPTARG
;;
h) usage
;;
\?) usage
;;
esac
done
[ -z "$cmd" ] && usage
fetchConfig() {
sed \
-e 's/[[:space:]]*\=[[:space:]]*/=/g' \
-e 's/;.*$//' \
-e 's/[[:space:]]*$//' \
-e 's/^[[:space:]]*//' \
-e "s/^\([^=]*\)=\([^\"']*\)$/\1=\"\2\"/" \
< ~/.aws/config
}
showProfileList() {
config=$(fetchConfig)
echo "${config}" \
| awk 'BEGIN{RS="["}/^profile/{gsub("\n"," ");print "[" $0}' \
| grep role_arn \
| sed -n -e "s/^\[profile \(.*\)\].*/\1/;p"
}
assumeRole() {
config=$(fetchConfig)
eval "$(echo "${config}" | sed -n -e "/^\[profile ${profile}\]/,/^\[/{/^[^;].*\=.*/p;}")"
prf=''
param=''
[ -n "${source_profile}" ] && prf="--profile ${source_profile}"
if [ -n "${duration}" ]; then
param="${param} --duration-seconds ${duration}"
fi
if [ -n "${mfa_serial}" ]; then
stty -echo; echo -n "Enter MFA code: "; read token_code; echo; stty echo
param="${param} --serial-number ${mfa_serial} --token-code ${token_code}"
fi
creds=($(aws ${prf} sts assume-role \
--role-arn $role_arn \
--role-session-name $profile_temp_$(date +%s) \
${param} \
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' \
--output text))
aws --profile $profile configure set aws_access_key_id ${creds[0]}
aws --profile $profile configure set aws_secret_access_key ${creds[1]}
aws --profile $profile configure set aws_session_token ${creds[2]}
echo "set complete."
}
case "$cmd" in
'show' )
showProfileList
;;
'assume' )
assumeRole
;;
esac
備考
external-id は自分が使っていないので未サポートです。必要な場合は適当に改変してください。
2020-02-07 追記: duration に対応