BLOGサブスレッドの日常

2024.04.09

aws-mfa-v2を利用してAWS CLIのMFAめんどくさいを解消する

ryosms

お久しぶりです! ryosms です

AWS CLI系のめんどくさいをなんとかしようシリーズ第2回(最終回)です。
前回の記事では「アクセスキーの管理がめんどくさい」を解消しました。
今回は「MFAが設定されている場合にAWS CLIがめんどくさい」をなんとかしていきます。

今回も基本的にmacOSを前提とした説明です。

MFAが設定されている時のめんどくささ #とは

組織のセキュリティポリシー等によっては、MFAの設定されていないIAMでは操作を制限するということはよくあります。
サブスレッドで運用しているAWSでも、基本的にはMFAセッションでないと各種リソースの操作はできないような制限を入れています。

このような制限がある場合、定期的にMFAのトークンを入力しないとCLIが使えないというめんどくささがあります。
また、ツールによってはMFAに対応していないアプリケーションがあったりします。(terraformとかterraformとか)

そこで、 aws-mfa-v2を利用してこのめんどくささを解消していくことにします。
これは、
なお、aws-mfaという似た名前のものもありますが、前回紹介したcredential_providerに対応してない && 更新が止まってるっぽいので v2 の方がオススメです。
(というかv2の本家で更新が止まってるからv2ができたのかな?)

ではやっていきましょう。

aws-mfa-v2 をインストールする

aws-mfa-v2 は PyPI で公開されているので、 PythonのPIPを利用してインストールします。

pip install aws-mfa-v2

これだけ、後はパスが通っていれば使えます。

(option) aws-mfa-v2 をインストールするPython環境を独立させる

サブスレッドの業務では主にPythonを利用しているので、global な Python環境を汚したくない && 案件ごとに環境を分けるため、 pyenv + pyenv-virtualenv(+ poetry)を利用してPythonのバージョンを切り替えています。
この運用の場合、アプリケーションをglobalなPython環境にインストールしていても案件用のPython環境に入っているとパスが通らない、ということがあるため aws-mfa-v2 専用の環境を用意して、aliasを設定してどこからでも利用できるようにしています。
(ここでは~/.zshrcに設定していますが、ご自身の環境に合わせて~/.bashrcなり~/.bash_profileなり好きに設定してください)
(「俺はaliasじゃなくて直接パスを通してやるぜ」という方もお好きにどうぞ)

インストールするPythonはなるべく新しめのもの、ということで本記事執筆時(2024年4月上旬)で最新の3.12.2を利用することにします。(3系のPythonならだいたい動くのではないかと思います。おそらくたぶんmaybe)

pyenv install 3.12.2
pyenv virtualenv 3.12.2 aws-mfa
pyenv shell aws-mfa
pip install aws-mfa-v2
echo "alias aws-mfa=\"`pyenv which aws-mfa\""` >> ~/.zshrc

aws-mfa-v2用のprofileを設定する

aws-mfa-v2が利用する元のprofieを設定する

前回の記事で紹介したprofileが既に設定されているものとして説明します。
まだAWS CLI用のprofileを設定していない場合はaws configure等で設定してください。
また、今回はMFAの設定されたIAMということなので、profileにmfa_serialを追加しています。

前回のprofileを今回の説明用に調整したものは以下のようになります。

[profile op-test-profile]
region = ap-northeast-1
output = json
credential_process = "/path/to/op-credential-helper.sh" "item_name"
mfa_serial = arn:aws:iam::123456789012:mfa/device-name

aws-mfa-v2でトークンを設定するprofileを作成する

aws-mfa-v2 の仕組みとして、 元になるprofile(今回であれば上記の op-test-profile )の認証情報(とMFAのトークン)を使って一時的なトークンを取得し、そのトークンを ~/.aws/credentials にセットすることで一定時間MFAを回避できる、という動きになります。

そのため、 aws-mfa-v2 がトークンをセットする profile を作成する必要があります。
aws-mfa-v2 が利用する profile は 「元のprofile名 + -mfa」という命名規則で作成します。
aws configure コマンドで新しい profile を作成します。 アクセスキー / シークレットキーは未入力のまま Enter していきましょう。

aws configure --profile op-test-profile-mfa

これで aws-mfa-v2 を利用する準備は完了です。

aws-mfa-v2 の使い方

準備が完了したら実際に使っていきましょう。
手順はたったの2ステップ!

  1. aws-mfa-v2 を利用して一時トークンを取得(して ~/.aws/credentials にセット)
  2. aws cli 等で利用する profile として、 aws-mfa-v2 用の profile (-mfaサフィックス)を指定する

aws-mfa-v2 で一時トークンを取得する

aws-mfa-v2 で一時トークンを取得するには、以下のコマンドを実行します。

aws-mfa --mfa-profile op-test-profile --token <MFAトークン>

以下の内容に注意しましょう。

  • 名前は aws-mfa-v2 だけど、コマンド名は aws-mfa
  • --mfa-profile オプションには、元の(-mfa サフィックスが付いていない)profile 名を指定する
  • --token オプションにMFAデバイスから取得したトークンを設定する

うまくいけば以下のようなメッセージが出力されます

Refreshed credentials for profile op-test-profile-mfa, they will expire in about 11 hours 59 minutes

デフォルトでは一時トークンの有効期限は12時間になっています。
これが長すぎるという場合は、 --duration オプションを利用して有効期限を秒数で指定します。
(環境変数 AWS_MFA_DURATION で指定することもできます)

他にもオプションがあるので、詳しくは help を見るか 公式のUsage を見ましょう。

取得した一時トークンを利用する

一時トークンが取得できたら、普通の profile と同様に使うだけです。

aws sts get-caller-identity --profile op-test-profile-mfa

とか

export AWS_PROFILE=op-test-profile-mfa
aws sts get-caller-identity

とか

終わり

というわけで、AWS CLI系のめんどくさいをなんとかしようシリーズ第2回(最終回)でした。
現場からは以上です。

おまけ(MFAトークンも1Passwordで管理している人向け)

1PasswordはMFAトークンの管理もできるので、1Passwordで管理している人もいると思います。
(1PasswordでID / PassとMFAを管理したら Multi Factor にならないというのはまた別のお話として)

1Password CLIをインストールしていれば、 op item get でOTP(1Passwordは「MFAトークン」ではなく、「One Time Password」扱い)を取得できます。
それを反映したコマンドは以下のようになります。(item_name の所は1Passwordに登録している名前に読み替えてください)

aws-mfa --mfa-profile op-test-profile --token `op item get "item_name" --otp`

ここまでやると、(M1以降とかのTouchID対応のmacであれば)コマンドを実行して指紋を読み込ませるだけでMFAを回避可能なAWSの認証情報が取れてしまうんですね。超便利

※ AWSの(ID / Password、)アクセスキー / シークレットキー、 OTP をすべて 1Passwordで管理することになるので、1Passwordの管理にはくれぐれもご注意ください。

この記事を書いた人

ryosms