aws-vault の印象ってどうですか?
クレデンシャルを平文で保管しなくても良くなるらしいけどめんどくさそう、あえて導入する必要もなさそう、そんなテキトーな理由で私は敬遠していました。
でも、ちゃんと使ってみたら最高に推せるツールでした。
これは布教したいと思ったので、3つのポイントで紹介します。
業務で数年AWSに携わっていても、知らない便利機能だったので、ぜひ!
推しポイント
1つ目 デメリットがない
私のローカル環境はOh My Zsh やawsp を用いて、AWSのプロファイルを設定していました。
この利便性が失われると想像していましたが、aws-vaultとOh My Zshとawspは全然共存できます。
一番シンプルな設定としては、クレデンシャルの平文管理を辞めるだけです。
profile設定しているconfigでcredential_process
を記述します。
[profile hoge-system]
region = ap-northeast-1
output = json
credential_process = aws-vault export --format=json hoge-system
その後、add実行でキーを保存します。
$ aws-vault add hoge-system
これで、ローカルの.aws/credentials
は不要になります。
aws-vault export --format=json hoge-system
を実行すると、キーチェーンからアクセスキーとシークレットキーが出力されるので、その情報がクレデンシャルに渡されるだけです。
この設定をしたうえで、awsp
を実行すれば、全て今まで通りです。
正確には、パスワード入力が一度必要とか、セッションとかキーチェーンのタイムアウトとかありそうですが、私はあまり気になっていません。
タイムアウト延ばせる方法もあるので、気になってから調べればOKだと思います。
また、aws-vaultだけでawsp相当の使用感も可能です。
そのためには、Oh My Zsh のaws-vaultプラグインも併せて用いると良いです。
設定は基本README通りで大丈夫です。
具体的な使用感について紹介します。
一度profileを設定すれば、余分なコマンド付与は要らない
awspでprofileを設定して、その後terraformコマンドを実行するケースも多いのでは無いでしょうか?
何回か実行するので、その都度余分なコマンドを付与するのはめんどくさいですよね。
これを普通にaws-vaultだけで出来ます。
# aws-vault exec hoge-system
Starting subshell /bin/zsh, use `exit` to exit the subshell
Restored session: 2025年 x月x日 x曜日 x時x分x秒 JST
#
# aws ...
# terraform ...
引数を入力せずexec
を実行するとサブシェルになって、profile(credential)が引き継がれます。
その後はawsコマンドでも、terraformコマンドでもそのまま実行して問題なしです。
Oh My ZshでAWSプロファイル名を表示
複数のAWSプロファイルを用いる方でしたら、CLI上でどのプロファイルが設定されているか確認したいですよね。
これも出来ます。
先ほどのプラグイン機能でも、prompt_aws_vault_segment
関数が用意されています。
実際のコードを確認すると、aws-vaultが使う環境変数を見やすいように処理しています。
関数使わなくても、$AWS_VAULT変数にプロファイル名が入るので、それを良い感じに表示させたらOKです。
こんな感じで、私の環境ではプロファイル名を表示しています。
2つ目 マネージメントコンソールへのログインが簡単
これ超便利です。
# aws-vault login hoge-system
これだけです。デフォルトのブラウザでマネコンが立ち上がります。
IAMユーザ名やパスワードの入力は必要ありません。
この応用的な方法もあります。
ブラウザの別プロファイルでマネコンにログイン
Oh My Zsh のaws-vaultプラグインの機能です。
# avli hoge-system
これだけで、好きなだけAWSにログインしたマネコンのブラウザが立ち上がります。
ブラウザにおいて別プロファイルなので影響し合うことが無く、ログアウトする必要もありません。
システム開発中で別システムの設定を参考したい時とかに、超超役立ちます。
使い心地の良い自作スクリプトを作るのは大変ですし、
もう、この2つ目だけで、十分aws-vaultのメリットがあると個人的に思います。
3つ目 スイッチロールが良い感じ
踏み台のAWSアカウントから、複数システムのアカウントへスイッチロールして操作する管理方法を採用していることもあると思います。
通常は困らないのですが、terraformコマンドをそのまま実行したい時とか、微妙に使い勝手が良くないんですよね。
それをaws-valutは良い感じにラップしてくれます。
[profile bastion-system]
region = ap-northeast-1
output = json
[profile hoge-system]
region = ap-northeast-1
output = json
; MFAは必要に応じて
mfa_serial = arn:aws:iam::XX:mfa/XX
role_arn = arn:aws:iam::YY:role/YY-role
source_profile = bastion-system
# aws-vault exec hoge-system // スイッチ先
Enter MFA code for arn:aws:iam::XX:mfa/XX: // MFA設定した場合
Starting subshell /bin/zsh, use `exit` to exit the subshell
Restored session: 2025年 x月x日 x曜日 x時x分x秒 JST
#
# aws ...
# terraform ...
スイッチロール用の普通なconfig
とaws-vault exec
で完結します。
このサブシェルの中で、awsコマンドでも、terraformコマンドでもそのまま実行すればOKです。
また、次の方法も超便利です。
aws-vault login でスイッチ先アカウントのマネコンにもログインできる
# avli hoge-system // スイッチ先
これで良いんです。
マッハじゃないですか?
アカウントID、IAMロール名、表示名とか入力する、あのロールの切り替え画面を操作せず、マネコンにログインできるんです。

こいつが要らないんです。
この快適さがあれば、踏み台AWSアカウント内だけでIAMユーザーやMFAを管理して、その他のシステムは全部スイッチロールで〜なんて運用ルールも余裕でいけると思います。
運用負荷的に爆アドです。
以上、aws-vaultの推しポイント紹介でした。
少しでも参考になれば幸いです。
オマケ
微妙にaws-vaultでうまく行かないケースについて整理しています。
awsコマンドやterraformコマンドが失敗するケース
サブセッションだと失敗するケースも存在します。
それはサブセッションが、sts.GetSessionToken
で認証情報を取得することに起因しています。
# aws-vault list
Profile Credentials Sessions
======= =========== ========
hoge-system hoge-system sts.GetSessionToken:XXmYYs
AWS公式でも制限がある旨記載されています。
この場合は、面倒ですがサブセッションにしなければ良いです。
以下のようにすれば、一時的な認証情報(GetSessionToken
)ではなく、長期的な認証情報(APIキーやシークレットキー)を用いて実行できるはずです。
親セッションで、引数で実行しましょう。
# aws-vault exec hoge-system -- terraform XX
ただ、IAM周辺とかニッチな機能以外は制限なさそうなので、サブセッションでほぼ問題無いと思います。
aws-vault login出来ない場合
IAMポリシーやコマンド実行条件によってaws-vault login出来ない場合もありました。
サブシェルで実行した場合:
マネコンへのログインは一時的な認証情報(sts.GetFederationToken
)を用います。
これが一時的な認証情報であるGetSessionToken
状態だと失敗します。
# aws-vault exec hoge-system
Starting subshell /bin/zsh, use `exit` to exit the subshell
Restored session: 2025年 x月x日 x曜日 x時x分x秒 JST
#
# avli
...
api error InvalidClientTokenId: The security token included in the request is invalid
Could not login
公式ドキュメントにもそれっぽい記載があります。
You must call the GetFederationToken operation using the long-term security credentials of an IAM user.
つまり、先ほど同様にサブシェルを実行せず、長期的な認証情報を用いればOKです。
親シェルで、引数で実行しましょう。
# aws-vault login hoge-system // avlでもOK
または
# avli hoge-system
サブシェルで実行出来る場合:
逆にサブシェルで実行出来る場合もあります。
これは先程のスイッチロールした時に該当します。
# aws-vault exec hoge-system // スイッチ先
Starting subshell /bin/zsh, use `exit` to exit the subshell
Restored session: 2025年 x月x日 x曜日 x時x分x秒 JST
# avli // OK
#
# aws-vault list
Profile Credentials Sessions
======= =========== ========
bastion-system bastion-system sts.GetSessionToken:XXmYYs
hoge-system - sts.AssumeRole:XXmYYs
スイッチロール先であるhoge-systemにおいては、GetSessionToken
ではなく、sts.AssumeRole
で権限を持っているので、GetFederationToken
も可能という仕様のはずです。
※なお、スイッチ元のcredentialをローカルに平文で持たない時(キーチェーンにある時)は、スイッチ先のSessions欄がAssumeRole
でなく-
表示になりました。AssumeRole
しているはずですし、login操作は問題なさそうでしたが、仕様不明です。スミマセン。
IAMポリシーが原因の場合:
セキュリティ確保のために、IAMポリシーでMFA強制させている場合もあると思います。
この場合、login操作はエラーになります。
...
Token on resource: arn:aws:sts:: ... with an explicit deny
明示的な拒否エラー。
これはGetFederationToken
のMFAサポートが不可なことに起因しているはずです。
MFA強制のポリシーを通らないので、拒否されます。
抜け道的な対策かもしれませんが、これにもAssumeRole
で対応出来ます。
MFAはスイッチ元で確認(長期的な認証情報やGetSessionToken
はMFAサポート可能)→スイッチ先ではMFA状態を確認する必要ないので、IAMポリシーでMFA強制させない→スイッチ先ではGetFederationToken
可能 といった感じです。
本質的な対策になっているかは、微妙かもです。