AWS CLI+MFAをラクにするOSS「Jimon-s/awsmfa」をリリースしました!

5 min read読了の目安(約4800字

本記事は、著者のブログから転記しています

どんな記事?

  • AWS CLI利用時のMFA認証突破をラクにするOSS「Jimon-s/awsmfa」の紹介記事
  • 日頃のめんどくさいにコミットする設計
  • AWS STS GetSessionToken API、AssumeRole APIの両方に対応しています

作ったもの

毎日やらなくてはいけないものの、操作が割と煩雑で、手動でやりつづけるにはちょっとつらい「CLI利用時のMFA」。

今回は、こんな日々のめんどくさいをラクにしてくれるOSS「Jimon-s/awsmfa」をリリースしたのでご紹介します。

ざっくり、どんなものかは以下のGIFをみていただければと!

https://github.com/Jimon-s/awsmfa

もし気に入っていただけたら、Zennのいいね!、GitHubのスターをいただけると喜びます!

インストール

homebrew

$ brew tap Jimon-s/awsmfa
$ brew install awsmfa

The others

リポジトリをClone後、
$ go install

or

Go 1.16以降
$ go install github.com/Jimon-s/awsmfa@latest

補完を効かせたい場合は、以下も実行

For zsh
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
↑はすでに追記済みであれば不要
$ awsmfa completion zsh > "${fpath[1]}/_awsmfa"
For bash
$ awsmfa completion bash > /usr/local/etc/bash_completion.d/awsmfa

セットアップ

「使いたいprofile名」+「--before-mfa」のprofileを~/.aws/credentials~/.aws/configに追記します。

が、まっさらから書くのはめんどうなので、スケルトン生成機能を搭載してます。
以下を叩いて、~/.aws/credentials~/.aws/configにひな形を追記しましょう。

$ awsmfa --generate-credentials-skeleton get-session-token >> ~/.aws/credentials

$ awsmfa --generate-config-skeleton get-session-token >> ~/.aws/config

※AssumeRole APIを使いたい場合は、get-session-tokenをassume-roleに置換してください。

で、追記されたひな形をエディタで埋めていきます。

GetSessionTokenを使う場合は、こんなイメージ。左下のGenerate automatically以外が必要です。

AssumeRoleの場合は、こんな感じです。

極力aws cli v2のデフォルトのkey名が、そのまま使えるように設計してあります。
(どうしても無理だったものは、prefixがawsmfa_xxxxとなっています)

使い方

$ awsmfa --profile 使いたいprofile名

を実行すると、

  • MFAコードの入力画面
  • リクエストパラメータ
  • パラメータの出どころ

が出てきます。問題なければ、そのままコードを入力すればOK。

これで、~/.aws/credentialsに一時クレデンシャルが自動追記されるので、あとは普段通りawsコマンドを使っていただければOKです。

$ aws s3 ls --profile 使いたいprofile名

応用編:デフォルトパラメータ

「profile名毎回入れるのめんどう」「全profileで共通のパラメータを使いたい」というケースもありますよね。

こういったケースに対応できるよう、awsmfaは独自の設定ファイルも保持しています。

$ awsmfa --generate-configuration-file true

で、~/.awsmfa/configurationにビルドインのデフォルト値が記載されたファイルが生成されるので、中身を書き換えてください。

パラメータの読み込み優先順位は、

  • cliオプション
  • 環境変数
  • shared credentialsファイル (~/.aws/credentials)
  • shared configファイル (~/.aws/config)
  • カスタム設定ファイル (~/.awsmfa/configuration)
  • ビルドインのデフォルト値

となっているので、カスタム設定ファイルが意図せずパラメータを上書きしにくくしています。

設計思想

以下はご興味あれば!

MFAでやらなきゃいけないこと

MFAが設定されているIAMユーザーでCLIを利用する場合、

STEP1

もともと払い出したアクセスキー&シークレットキーで、

  • AWS STS GetSessionToken API + with MFAコード
  • AWS STS AssumeRole API + with MFAコード

のどちらかを実行

STEP2

↑のレスポンスで、色々なAPIへアクセスできる一時的な

  • アクセスキー
  • シークレットキー
  • セッショントークン

が返ってくるので控える

STEP3

控えたクレデンシャルを

  • 環境変数
  • Shared credentialsファイル(~/.aws/credentials )

のどちらかに登録して、aws cliの各種コマンド実行

のフローを取ります。

ただ、CLIコマンドを叩くたびに、毎度オプションが大量についた長めのコマンドを実行するのはなかなかにめんどくさいですし、~/.aws/credentialsを手作業で毎回メンテするのはつらみがありすぎますね。

もう少し詳しく分解すると

コマンドの打ち込み&実行フェーズでは

  • 打ち込むコマンドがMFA認証コード--token-codeまで含めた「長めなコマンド」になるので、見通しが悪い
  • ↑をコピペで解決しようにも、MFAコード部分を毎回書き換えなくてはならないので、カーソル移動が発生してめんどくさい
  • さらに--profileまで指定していると、変更箇所2倍でさらにめんどくさい

がつらいでかなと。

特に3番目は、僕のような複数のAWS環境をいったりきたりしている人にとっては、--profileはほぼ必須(ポカよけでdefaultは使わないようにしている)なので死活です。

返ってきた一時クレデンシャルを保存するフェーズでは

  • レスポンスのJSON文字列から、アクセスキー、シークレットキー、セッションキーを個別に抜き出す必要がある
  • 抜き出した情報を毎回エディタで~/.aws/credentialsに書かなくてはいけない

のがつらいですね。

これを回避するよくある方法は「環境変数に保存するワンライナーを書く」だと思うんですが、先の理由と同様にポカよけで環境変数も使わないようにしている僕にはマッチせず。

credentialsファイルの書き換えまで、ワンライナー化すればいいじゃん!」と言われそうですが、(特にprofileを指定した書き換えまでやろうと思うと)なかなかに複雑な作りになってしまい、将来の自分に嫌われそうな雰囲気がただよっていたので、その線はなしにしました。

また、ちょっと本筋とは離れますが、aws cliのパラメータの読み込み順序って、結構複雑じゃないですか。

例えば、cliオプション、環境変数、~/.aws/credentials~/.aws/configの全部にリージョン書いたらどこが最優先になるかパッといえますか?
特に、STS APIはオプションが多く、記述があっちこっちに散らばりがちなので、このあたりも見える化したいなと。

他のOSSもあるけれど

自作する前段階で既存を探してはみたんですが、

  • ~/.aws/credentials~/.aws/configにaws cliのデフォルトとは違う独自キーのパラメータを書かなくてはいけない
  • 一時クレデンシャルの有効期限の指定ができない
  • GetSessionToken APIとAssumeRole APIの切り替えがブラックボックス化されてる
  • ↑を叩きにいくリージョン指定ができない
  • どこに書いたパラメータが優先されたか不明瞭

なものが多く、僕のユースケースにぴったりハマるものがみつけられず。探すよりも作ったほうがはやいのでは、となった次第です。

なので目指したのは

  • コマンド実行時にカーソル移動をしなくてよい
  • ~/.aws/credentialsの書き換えまで自動でやってくれる
  • 使っているパラメータの出どころが明確
  • ~/.aws/credentials~/.aws/configに書く独自パラメータは最小限
  • 一時クレデンシャルの有効期限、叩き先リージョンのような細かな部分まで指定できる
  • GetSessionToken APIとAssumeRole APIの切り替えができる

贅沢ですが、これを全て叶える全部入りを目指しました。

できあがったもの

で、完成したのがこちら!

https://github.com/Jimon-s/awsmfa

まさしく全部入り!という感じです。

おわりに

自分で作ってみると学びが深いですね!

割といろんなユースケースに耐える作りになっていると思いますので、お気軽にお試しくださいー。

Zennのいいね!、GitHubのスターをいただけると喜びます!

https://github.com/Jimon-s/awsmfa