お世話になってたディレクトリ移動だけでAWSのクレデンシャルを切り替える仕組みがM1 Macで動かなかったので替わりのスクリプトを書いた
私がこのDevelopers IOでも屈指の良エントリだと思っているのが、以下の佐伯さんのエントリです。
ディレクトリ移動をするだけでAWSのクレデンシャルを切り替えてくれるので、複数のAWSアカウントに対してCLIベース(私はTerraformを使うことが多い)で作業をするような方にはとてもおすすめです。一度お試しください。
M1 Macでは動かなかった
最近開発環境をM1 Macに変えました。するとこの仕組みが動作しませんでした。
環境情報
- MacBook Pro (13-inch, M1, 2020)
- チップ: Apple M1
- OS: MacOS Big Sur (バージョン11.6.2)
原因
上記仕組みはdirenvとassume-roleという2つのツールを組み合わせて実現されているのですが、assume-roleがM1に対応していないようです。
% assume-role zsh: segmentation fault assume-role
替わりのスクリプトを書いた
方針
この仕組みを諦めるのにはあまりにも便利なので、代替案を考えました。前述の仕組みの概要はざっくりと以下の様になっています。
- direnvで所定のディレクトリに移動すると予め設定したスクリプトが実行される
- 上記スクリプトの中でassume-roleを、カレントディレクトリを引数にして実行
- クレデンシャル取得できる(認証完了)
なので、2.でassume-roleを実行しているスクリプトの部分を、assume-roleコマンドを使わず実現できればよいわけです。
詳細
最終的に.envrc
の中身を以下にすることで実現できました。
eval target_profile=$(basename $(pwd)) echo target profile is $target_profile read -p "MFA Code: " mfa_code AWS_STS_CREDENTIALS=`aws sts assume-role --profile default --role-arn $(aws configure get ${target_profile}.role_arn) --role-session-name ${target_profile}-session --serial-number $(aws configure get ${target_profile}.mfa_serial) --token-code $mfa_code`;export AWS_ACCESS_KEY_ID=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.AccessKeyId'`;export AWS_SECRET_ACCESS_KEY=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SecretAccessKey'`;export AWS_SESSION_TOKEN=`echo "${AWS_STS_CREDENTIALS}" | jq -r '.Credentials.SessionToken'`
1-2行目 ターゲットプロファイル名の取得
この仕組みでは、カレントディレクトリ名 = プロファイル名となります。そのカレントディレクトリ名を取得して変数に格納します。
3行目 MFAコード入力
私はMFA必須のポリシーを持っているユーザーからしかスイッチしないので、標準入力からMFAコードを取得します。
4行目
aws sts assume-role
コマンドで取得した一時クレデンシャルの情報を環境変数にセットします。この部分は以下の若槻さんのエントリを参考(丸々拝借)しています。若槻さんありがとうございます!
使用例
使い勝手としては従来のassume-roleを使っている場合と同じです。
クレデンシャルファイルにassume role元のユーザーとassume role先のロールを設定します。
[default] aws_access_key_id=xxxxxxxxxxxxxxxxxxxx aws_secret_access_key=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
[profile kazue-sandboxes] source_profile=default role_arn=arn:aws:iam::012345678901:role/kazue mfa_serial=arn:aws:iam::111111111111:mfa/kazue
次にassume role先プロファイル名と同じ名前のディレクトリを作成し、そこに前述の.envrc
を置きます。そして作ったディレクトリに移動します。
% cd ~/project/kazue-sandboxes/ direnv: error /Users/kazue.masaki/project/kazue-sandboxes/.envrc is blocked. Run `direnv allow` to approve its content
初回はdirenv allow
というコマンドを実行する必要があります。2回目からは不要です。
direnv allow
を打つと(2回目からはディレクトリ移動するだけで)MFA Codeを訊かれます。入力すると環境変数がセットされ、認証完了です。
% direnv allow direnv: loading ~/project/kazue-sandboxes/.envrc target profile is kazue-sandboxes MFA Code: 323006 direnv: export +AWS_ACCESS_KEY_ID +AWS_SECRET_ACCESS_KEY +AWS_SESSION_TOKEN % aws sts get-caller-identity { "UserId": "AAAAAAAAAAAAAAAAAAAAA:kazue-sandboxes-session", "Account": "012345678901", "Arn": "arn:aws:sts::012345678901:assumed-role/kazue/kazue-sandboxes-session" }