🌏

【aws-vault】AWSマルチアカウント環境でのCredential管理

2022/09/01に公開

はじめに

AWS を利用する上で安全に IAM ユーザ・ロールの Credential(認証情報)を扱うことが重要です。
この認証情報が流出してしまうと、アカウントが不正に利用されて大切なデータが流出したり、AWS リソースを大量に使用されてクラウド破産につながることもあります。
そのため、Credential は安全な場所に安全な方法で保管する必要があります。
特に AWS をマルチアカウントで運用するの場合は、各アカウントに IAM リソースが存在するため、アカウントや IAM リソースが増えるごとにこの Credential 管理が煩雑になっていきます。
ここでは aws-vault とスイッチロールを組み合わせた方法で安全かつ便利に Credential を使用・管理する方法をご紹介します。
※一部 MacOS を前提とした手順になっておりますのでご了承ください。

AWS Credential 管理の課題

代表的な AWS の Credential として AK/SK(AccessKey と SecretAccessKey)があります。
ローカル端末から AWS CLI を実行したり、ソースコード上で SDK を使用する場合には、IAM ユーザで AK/SK を発行します。
その際に問題になるのは AK/SK の管理です。
AWS 公式の手順に則ると AK/SK の情報は環境変数か認証情報ファイル(~/.aws/credentials)に保管します。
Credential を平文で保管するため、PC が盗難にあったり、ウイルスに感染した際に Credential が流出する恐れがあります。

aws-vault とは

AWS の AK/SK を安全に保存・利用するための OSS ソフトウェアです。aws-vault
OS の安全なキーストアに AK/SK を格納して管理することができます。
aws-vault は AWS の STS というサービスを利用し、GetSessionToken または AssumeRole API コールを介して一時的な Credential を生成して使用します。
これは短時間で失効するため、Credential が漏えいするリスクが低減されます。

aws-vault のインストール

MacOS の Homebrew を使用する場合は以下のコマンドを使ってインストールします。

$ brew install --cask aws-vault

他にも Windows 等の環境に合わせたインストール方法があるので、自身の環境に合わせた方法でインストールしてください。
https://github.com/99designs/aws-vault#installing

aws-vault 設定(全体像)

下記の図が aws-vault で設定が必要な IAM リソースの全体像です。
まず、各アカウントへの切り替え元となる親アカウントを決めます。
そのアカウントに作成した IAM ユーザから各アカウントの IAM ロールを引き受けて(Assume Role して)権限を切り替えることで複数アカウントでの Credential の使用を可能にします。

切り替え元 IAM ユーザ作成

親アカウント上で切り替え元となる IAM ユーザを作成します。

IAM ユーザ作成

AK/SK の作成のため、Access key の項目をチェックしてください。

IAM ポリシーは以下のようにします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": "*"
        }
    ]
}

ユーザが作成されたら AK/SK の情報を控えてきます。

MFA 設定

先ほど作成した IAM ユーザへ MFA 設定を行います。
まさか AWS を使用していて MFA 設定をしたことがない不届き者はいないと思いますので詳細な手順は割愛します。
思い思いの方法で MFA 設定をしてください。
MFA 設定ができたら「Assigned MFA device」の ARN を控えておきます。

ちなみに MFA 設定をしないと aws-vault を使用して作成した一時的な Credential を使用して IAM リソースの作成ができません。

aws-vault 設定 (IAM ユーザ)

PC のターミナルを開き、以下のコマンドを実行します。
IAM ユーザ作成時に控えておいた AK/SK の情報を入力します。
credential name は任意の名前です。

$ aws-vault add <credential name>
Enter Access Key ID: XXXXXXXXXXXXXXXXXXXX
Enter Secret Access Key:
Added credentials to profile "xxxxxx" in vault

その後、以下のコマンドを実行し、”~/.aws/config” を編集します。
上記の作業によって profile が追加されているはずです。
mfa_serial には MFA 設定時に控えておいた MFA デバイスの ARN を入力します。

$ vi ~/.aws/config

[profile <credential name>]
region=ap-northeast-1
output=json
mfa_serial=<mfaのarn>

これで切り替え元の IAM ユーザの設定は完了です。

切り替え先 IAM ロールの作成

今度は切り替え先のアカウントへ移動して切り替え先の IAM ロールを作成します。
任意の IAM ポリシーを付与した IAM ロールを作成します。
作成した IAM ロールの ARN を控えておきます。

その後「信頼関係」タブを開き、以下の内容で更新します。
Principal の<親アカウントの ID>を切り替え元 IAM ユーザを作成した親アカウントの ID に変更してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<親アカウントのID>:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        }
    ]
}

aws-vault 設定 (IAM ロール)

再度”~/.aws/config” を編集して IAM ロールに関する profile を追加します。
以下の例のような状態に編集してください。

$ vi ~/.aws/config

[profile jumpuser]
region=ap-northeast-1
output=json
mfa_serial=arn:aws:iam::xxxxxxxx:mfa/jumpuser

# 以下を追加
[profile role_name]
source_profile=jumpuser  # 切り替え元IAMユーザのプロファイル
role_arn=arn:aws:iam::xxxxxxx:role/role_name  # 切り替え先ロールのARN
mfa_serial=arn:aws:iam::xxxxxxxx:mfa/jumpuser  # 切り替え元IAMユーザのMFAデバイスのARN

これで切り替え先の IAM ロールの設定は完了です。
複数アカウントを運用されている方は上記の IAM ロールに関する手順をそれぞれのアカウントで実施してください。

なお、アカウントが増えてくると各アカウントのロールごとの上記の設定情報の量が増えてきます。
切り替え先ロールの ARN 以外の内容は各ロールで共通のため、
私の場合は以下のように1つ雛形となる profile(switchrole)を作成して、各ロールの profile からは雛形の profile を include_profile で参照するようにしています。

[profile jumpuser]
region=ap-northeast-1
output=json
mfa_serial=arn:aws:iam::0000000000000:mfa/jumpuser

[profile switchrole]
region=ap-northeast-1
output=json
source_profile=jumpuser
mfa_serial=arn:aws:iam::000000000000:mfa/jumpuser

[profile account_a]
role_arn=arn:aws:iam::111111111111:role/role_name
include_profile=switchrole

[profile account_b]
role_arn=arn:aws:iam::222222222222:role/role_name
include_profile=switchrole

[profile account_c]
role_arn=arn:aws:iam::333333333333:role/role_name
include_profile=switchrole
~

動作確認(ロール切り替え〜CLI 実行)

以下のコマンドを実行します。
<role_name>は上記の IAM ロールの aws-vault 設定で [profile role_name]に指定した名前と同じです。
キーチェーンのパスワードを求められるので入力します。
MFA を求められるので MFA コードを入力します。

$ aws-vault exec <role_name>
Enter MFA code for arn:aws:iam::000000000000:mfa/jumpuser:

認証が成功したら(特に成功した旨のメッセージは出ないです)
ロールに付与した権限で実行できる AWS CLI を実行してみましょう。
設定に問題なければ実行できるはずです。

$ aws s3 ls
2022-08-12 19:09:19 bucket-xxxxxxxxxx
2022-08-25 16:38:47 bucket-yyyyyyyyyy

補足

MFA を使用している場合には aws-vault によって使用できる AWS Credential は 1 時間で失効します。
失効した状態のままで Terraform コマンドを実行すると以下のエラーが発生します。

 Error: error configuring Terraform AWS Provider: no valid credential sources for Terraform AWS Provider found.

上記が発生した場合はターミナルで"exit"と入力して aws-vault を解除し、再度”aws-vault exec”を実行してから Terraform コマンドを実行してください。
MFA コードは一度入力すると 12 時間程度は再度入力しなくても”aws-vault exec”を実行できます。

まとめ

今回は AWS マルチアカウント環境での Credential 管理について解説しました。
開発用・本番用などで複数の環境を使用する場合はアカウントごと分けるのが AWS のベストプラクティスとなっているため、昨今は複数アカウント運用が当たり前になっています。
私の場合も 自社 Web サービスの開発・本番環境用や検証用等で複数のアカウントを運用しており、各アカウントに切り替えて Terraform コマンドを実行する際に上記の機能を重宝しています。
aws-vault と Assume Role の仕組みを組み合わせることによって、必要な AK/SK と MFA 情報を最小限にとどめ、新しいアカウントが追加される際のスケーラビリティも確保できるため、利便性を損なわずに安全に Credential を管理することができます。
どなたかの参考になれば嬉しいです。

参考

https://sebenkyo.com/2021/03/09/post-1924/

https://dev.classmethod.jp/articles/aws-vault/

Discussion