[小ネタ]ディレクトリ移動した際に自動で一時クレデンシャルを取得・設定する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、AWS事業部の佐伯です。

同様の使い方をしてる方は多いかもしれませんが、今回はdirenvを使用してCLIでのAssumeRoleを簡単にする小ネタを書きたいと思います。

目的

権限の分離や請求情報の明確化のためAWSアカウントを分割している場合、全てのAWSアカウントにIAMユーザーを作成すると管理が煩雑になるため、IAMユーザーの管理はひとつのAWSアカウントにまとめ、その他のAWSアカウントへはスイッチロールで利用しているケースがあるかと思います。

しかし、各種CLIツールを使用するためには一時クレデンシャルをスイッチ先のAWSアカウントから取得し、環境変数に設定する必要があります。毎回AWS CLIを実行するのは面倒なので、今回はディレクトリ移動した際に自動で一時クレデンシャルを取得・設定し、楽をしようというのが目的です。

使用するツール

direnv

direnvは特定のディレクトリ移動した際に環境変数を設定してくれるツールです。
少し古いですがこちらの記事でも紹介されています。

remind101/assume-role

assume-roleはAWS CLIの設定ファイル(~/.aws/config)と認証情報ファイル(~/.aws/credentials)を読み込み、一時クレデンシャルを取得します。GitHubで検索すると同様のツールがいくつかありますが、私がこのツールを選んだ理由は以下のとおりです。

  • 独自の設定ファイルを作成する必要がない(~/.aws/config, ~/.aws/credentialsはどちらもAWS CLIの設定ファイル、認証情報ファイル)
  • 環境変数に設定するためのコマンドを標準出力することができる

設定

macOS(Sierra)、bashの環境で確認しています。その他OSやシェルを利用の場合は各ツールのREADME.mdをご確認ください。

direnvのインストールおよびセットアップ

Homebrewでdirenvをインストールし、~/.bashrcにフックの設定をします。

$ brew install direnv
$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
$ exec $SHELL -l

remind101/assume-roleのインストール

Homebrewでremind101/assume-roleをインストールします。

$ brew install remind101/formulae/assume-role

AWS CLI設定

AWS CLIを使用してスイッチ元のAWSアカウントで作成したIAMユーザーのアクセスキーとシークレットアクセスキーを設定をします。

$ aws configure
AWS Access Key ID [None]: AKIAIOEXAMPLEEXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEXAMPLEKEYEXAMPLEKEYEXAMPLEKEY
Default region name [None]: ap-northeast-1 #任意のリージョン
Default output format [None]: json #任意のフォーマット

AWSアカウントIDおよびロール名を指定した、スイッチ先のAWSアカウントを名前付きプロファイルで設定します。

[default]
region = ap-northeast-1
output = json

[profile account-a]
source_profile = default
role_arn = arn:aws:iam::<AWSアカウントID>:role/<ロール名>

remind101/assume-roleはMFAが必須なロールでのAssumeRoleにも対応していますので、その場合は mfa_serial の設定も行います。こちらのエントリを参考にしてください。

プロファイル作成

ディレクトリに移動した際にdirenvがロードする.envrcファイルを作成します。

$ cd path/to/account-a
$ echo 'eval $(assume-role $(basename $(pwd)))' >>.envrc

.envrcがカレントディレクトリに作成されるとエラーメッセージが出力されますので、direnv allowで.envrcのロードを許可します。direnv allow実行後、.envrcがロードされ各環境変数設定されます。

direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
$ direnv allow
direnv: loading .envrc
direnv: export +ASSUMED_ROLE +AWS_ACCESS_KEY_ID +AWS_SECRET_ACCESS_KEY +AWS_SECURITY_TOKEN +AWS_SESSION_TOKEN

.envrcの内容補足

assume-roleコマンドにカレントディレクトリを引数として渡しており、カレントディレクトリは名前付きプロファイルと同じ名前としているのでassume-role account-aの実行結果をevalでコマンドとして実行し、環境変数に設定しています。

eval $(assume-role $(basename $(pwd)))

環境変数に設定しているだけなのでenv | grep AWSなどで取得した一時クレデンシャルの内容も確認できます。

$ env | grep AWS
AWS_SESSION_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXX
AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXX
AWS_SECURITY_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXX

一時クレデンシャルの有効期間

assume-roleで取得する一時クレデンシャルの有効期間はデフォルトで一時間です。有効期間切れとなった場合はdirenv reloadで再取得できます。

環境変数のアンロード

direnvで設定された環境変数は上位ディレクトリに移動するとアンロードされます。下位ディレクトリの場合は引き続き環境変数が有効となります。

$ cd ..
direnv: unloading

まとめ

.envrcにはアクセスキーやシークレットアクセスキーを設定していないのでGitの管理対象にし、チームで運用されている場合も有効かと思います。

私自身のユースケースとしては、多くのAWSアカウントを触る機会があるので、各種ツール類のテンプレートと.envrcのテンプレートを保存した、プロジェクト用のテンプレートディレクトリを作成してコピーするといった運用をしています。