AWSアカウントを組織で管理していると複数アカウント利用するケースは多いかと思う。別のアカウントに切り替えるには、WebコンソールからSwitch Roleすればよい。そして以下のように $HOME/.aws/config
と $HOME/.aws/credentials
を設定すればAWS CLIからもSwitch Roleできる。
$ cat $HOME/.aws/credentials
[main-account]
aws_access_key_id = ACCESS_KEY_ID
aws_secret_access_key = SECRET_ACCESS_KEY
$ cat $HOME/.aws/config
[profile sub-account]
source_profile = main-account
role_arn = ROLE_ARN
mfa_serial = MFA_SERIAL_ARN
region = ap-northeast-1
$ aws s3 ls --profile sub-account
(sub-accountのS3 bucketのリスト)
ただこれだと、 ACCESS_KEY_ID
と SECRET_ACCESS_KEY
を平文で保存することになりやや脆弱なのでenvchainを使いたい。envchainはmacOSのKeychainやLinuxのGNOME Keyring等で暗号化保存したcredentialsを復号して環境変数に設定してくれる。使い方はREADMEの通り。
github.com
envchainを併用する場合 $HOME/.aws/credentials
と $HOME/.aws/config
を以下のように設定すればSwitch Roleできる。
$ cat $HOME/.aws/credentials
(envchainに寄せたのでcredentialsは空)
$ cat $HOME/.aws/config
[profile sub-account]
credential_source=Environment
role_arn = ROLE_ARN
mfa_serial = MFA_SERIAL_ARN
region = ap-northeast-1
$ envchain aws-main-account env
...
AWS_ACCESS_KEY_ID=ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY=SECRET_ACCESS_KEY
AWS_DEFAULT_REGION=ap-northeast-1
$ envchain aws-main-account env aws s3 ls --profile sub-account
(sub-accountのS3 bucketのリスト)
$HOME/.aws/config
で credential_source=Environment
を足しておかないと Partial credentials found in assume-role, missing: source_profile or credential_source
というエラーが出るので注意。また、profileの指定は --profile
オプションでのみ可能で、環境変数 AWS_PROFILE
で指定することはできない。このあたりはドキュメントにも載っている。
awscli.amazonaws.com
ところでこの方法だと $HOME/.aws/cli/cache/*.json
に一時的なcredentialが吐き出されてしまい、envchainを使う意図としてはやや片手落ちな感がある。ではどうするかというと、AssumeRoleのコマンドを手で発行して、返ってきたcredentialを環境変数に設定する。具体的な方法は以下の記事が詳しい。
dev.classmethod.jp
自分の場合は以下のようなラッパーを書いて利用している。
github.com
このように使う:
$ cat $HOME/.aws/config
[profile sub-account]
role_arn = ROLE_ARN
mfa_serial = MFA_SERIAL_ARN
region = ap-northeast-1
$ envchain aws-main-account env aws-switch-role sub-account
Enter MFA code for MFA_SERIAL_ARN:
$ (sub-account) aws s3 ls
(sub-accountのS3 bucketのリスト)
やっていることとしては aws sts assume-role
で取得したcredentialを環境変数に設定して $SHELL
を新しく立ち上げているだけ。一時的なcredentialはこのプロセス内でのみ有効になるので、平文で保存されるよりは幾らかマシということにしている。(2022-08-12 追記: sudo cat /proc/$PID/environ | sed 's/\x00/\n/g'
とかすれば読み取れてしまうので気持ちの問題ではある…)
ところでこの方法だとcredentialを環境変数に設定するのでAWS CLIの利用時にprofileを指定する必要がなくなるが、逆に現在どのprofileに対して操作しているのかが分かりづらくなる。そこで自分は $SHELL
を立ち上げるときに本来必要ない環境変数 AWS_PROFILE
を一緒に設定してあげて、これが設定されていたらプロンプトの表示を変えている。
$ cat $HOME/.zshrc
...
PROMPT="%{${fg[yellow]}%}%(!.#.$) $([[ -n $AWS_PROFILE ]] && echo "($AWS_PROFILE) ")%{$reset_color%}"
...
立ち上がったシェルを終了すれば元に戻れるので、一時的にセッションを張る使用感になる。
現実的にはひとつめのパターンやふたつめのパターンで十分ということもありそう。社のセキュリティーポリシーや自分のセキュアにしたい気持ちと相談して選択されたい。