AWSを使っていると、APIの呼び出しにMFA認証を必須とすることが多いかと思います。
コンソールではログイン時に認証コードを入力しますが、AWS CLIを使用する場合は
get-session-token
コマンドで一時的な認証情報を取得し、credentialsファイルを更新するか、
環境変数を設定する必要があります。
一時的な認証情報はAWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
、AWS_SESSION_TOKEN
の3つでワンセットです。
複数のアカウントを使用しなければならないときはその数だけコマンドを実行し、credentialsファイルのプロファイルを編集する必要があります。
私は最近毎日6アカウントくらい使うのでとても面倒でした。
そこでcredentialsファイルを簡単に更新できるツールaws-mfa-profile
を作りました。
目次
前提条件
aws sts get-session-token --serial-number <value> --token-code <value>
で一時的な認証情報を取得している- Rustのプロジェクトがビルドできる環境
使い方
aws-mfa-profileはオプション-p
(あるいは--profile
)で指定されたプロファイル名をもとに、mfa.jsonからエントリを探し、sts:GetSessionToken
APIを叩いて一時的な認証情報を取得し、credentialsファイルを更新します。
mfa.jsonはあらかじめ作成しておく必要があります。
以下はヘルプオプションの実行結果です。
$ aws-mfa-profile -h aws-mfa-profile USAGE: aws-mfa-profile [OPTIONS] OPTIONS: -c, --credentials-file <CREDENTIALS_FILE> aws credentials file name [default: 'credentials'] -h, --help Print help information -m, --mfa-file <MFA_FILE> mfa file name [default: 'mfa.json'] -p, --profile <PROFILE> aws profile name [default: 'default']
例えば、dev
プロファイルでget-session-token
を実行し、dev_mfa
プロファイルの認証情報を更新する場合は次のようにします。
この時のトークンコードは123456
です。
$ aws-mfa-profile -p dev [input] token code: 123456 Success! "credentials" file has been updated.
credentialsファイルにdev_mfa
プロファイルのエントリがない場合は[dev_mfa]
として自動作成されます。
もしもmfa.jsonやcredentialsファイルがカレントディレクトリにない場合は-m
オプションや-c
オプションで指定します。
$ aws-mfa-profile -p dev -m .aws/mfa.json -c .aws/credentials [input] token code: 123456 Success! "credentials" file has been updated.
mfa.jsonの作成
-m
オプション(あるいは--mfa-file
)で指定するmfa.jsonは次のようなフォーマットになっています。
[ { "profile": "your profile name in .aws/credentials", "serial": "your mfa device id", "mfa_profile": "your profile name in .aws/credentials" } ]
次に示すのはmfa.json
の例です。
[ { "profile": "default", "serial": "default_mfa_device_id", "mfa_profile": "mfa" }, { "profile": "dev", "serial": "dev_mfa_device_id", "mfa_profile": "dev_mfa" }, { "profile": "prd", "serial": "prd_mfa_device_id", "mfa_profile": "prd_admin_role" } ]
この例の場合、ひとつ目のエントリはdefault
プロファイルを使用してget-session-token
を実行し、--serial-number
にはdefault_mfa_device_id
が使用されます。
取得した認証情報はcredentialsファイルのmfa
プロファイルに設定されます。
aws-mfa-profileの実行例
.aws/config
、.aws/credentials
、.aws/mfa.json
の内容を含めた完全な例を示します。
カレントディレクトリは~/.aws
とします。
$ cd ~/.aws $ ls config credentials mfa.json
config
ファイルの内容は以下です。
[default] region = us-east-1 [dev] region = us-east-1 [dev_mfa] region = us-east-1
credentials
ファイルの内容は以下です。
[default] aws_access_key_id = hoge_default aws_secret_access_key = fuga_default [dev] aws_access_key_id = hoge_dev aws_secret_access_key = fuga_dev
mfa.json
ファイルの内容は以下です。
[ { "profile": "dev", "serial": "arn:aws:iam::000000000000:mfa/device_id", "mfa_profile": "dev_mfa" } ]
dev
プロファイルで一時的な認証情報を取得し、credentialsファイルのdev_mfa
プロファイルを更新します。
$ aws-mfa-profile -p dev [input] token code: 123456 Success! "credentials" file has been updated.
実行後のcredentialsファイルの内容は以下です。
[dev_mfa]
のエントリが作成され、一時的な認証情報が設定されます。
もしエントリが既に存在する場合は認証情報に関する値の部分が更新されます。
[default] aws_access_key_id = hoge_default aws_secret_access_key = fuga_default [dev] aws_access_key_id = hoge_dev aws_secret_access_key = fuga_dev [dev_mfa] aws_access_key_id = hoge_dev_mfa aws_secret_access_key = fuga_dev_mfa aws_session_token = token
実行前のcredentialsファイルはcredentials.bkp
としてバックアップされます。
$ ls
config credentials credentials.bkp mfa.json
まとめ
このツールは結構便利で毎日使っています。credentialsファイルの更新は結構面倒だけど頻繁に行う作業なので、同じようなツールを作って使っている人も多いと思います。
最近は仕事もすべてAWS関連のものになり、AWS SDKを使ってちょっとしたツールを作ることが多くなりました。
昨年12月にAWS SDK for Rustのデベロッパープレビューが発表され、Rustでツールを作れることが嬉しいです。
ただLambdaなどで動かすものになるとランタイムがないのでPythonで書いています。やっぱりちょっとしたことをするにはPythonがルーズに書けて便利だなって思ったりします。
そういえば最近そのちょっとしたことで感動したことがありました。
S3 BatchOperationのLambda関数の呼び出しオペレーションで、数万個のオブジェクトの書き換え処理を行ったとき、1~2時間かかるかと思っていたものが数分で完了しました。
メトリクスにはLambdaの同時実行数が900を超えたことが示されていて、スケーラブルとは斯くも素晴らしいことかと感動しました。