目次
はじめに
特定のアカウントから複数アカウントへスイッチロールする仕組みを構築する機会がありました。スイッチ元IAMロールを踏み台のように使うことで、作業先アカウントの取り違えを防ぐという仕組みを検討していましたが、CUIでしか実現できないということがわかり断念していました。アイデアを実現できないことが悔しく、せっかくなので試してみました。
例えばスイッチ元がAccount A
、作業先がAccount B
の場合、account-a-role-1
にスイッチロールした後、スイッチ先アカウントを間違えて指定(Account C
やAccount D
を指定)しても、スイッチロールが不可能なように設定することで作業先の誤りを防ぐイメージ。
要約
- ロールの連鎖とは1 つのロールの認証情報を使用して別のロールを引き受けること
- 基本的にロールの連鎖はCUIでしか実現できないが、AWSumeを使うことによりロールの連鎖でコンソールログインが可能
- AWSumeとはセッショントークンを管理し、ロールの資格情報を引き受ける便利なツール
ロールの連鎖
ロールの連鎖は公式ドキュメントで下記のように紹介されていました。
1 つのロールの認証情報を使用して別のロールを引き受けることをロールの連鎖と呼びます。
例えば下記のようにAccount AのIAMユーザーでaccount-a-roleにスイッチロールし、
account-a-roleにスイッチロールした状態でその認証情報を利用してaccount-b-roleにスイッチロールする、ということもロールの連鎖に該当すると理解しました。
また、ドキュメントに明示はされていないものの、マネジメントコンソール上でロールの連鎖はできないように読み取れる記述がありました。(実際試してみましたが、やはりできませんでした)
ロールの連鎖は、AWS CLI または API を使用して 2 つ目のロールを引き受けるロールを使用する場合に発生します。
ですが、AWSumeというツールを使うことでこれが実現できるようです。
AWSumeとは
AWSumeとはセッショントークンを管理し、ロールの資格情報を引き受ける便利なツールです。(AWSがリリースしている公式のツールではないようです。)
このツール自体の紹介は下記で行われていますのでご参照いただくと良いと思います。
このツールを使うことでマネジメントコンソール上でロールの連鎖ができるようになるか(正確にはロールの連鎖後、マネジメントコンソールの操作ができる)以降に検証してみた結果を記載します。
構成
ここからはAWSumeでマネジメントコンソール上でのロールの連鎖を検証した結果を記載します。下記のように簡単な構成で実施しました。(※管理が大変になるため2アカウント、1ユーザーのみとしています)
ちなみに、個人で複数アカウントを払い出すのが初めてだったため、「複数アカウントを払い出すとなると、12 ヶ月の無料利用枠が複数アカウントで使えるようになるが、それは良いのだろうか」という疑問が湧いたので、サポートに問い合わせてみました。基本的には問題ないと回答いただきました。ただし、Organizationsを利用する際は注意が必要なようでした。
IAMロール/ポリシーの準備
まずは、Account AでIAMロール(account-a-role-1)とポリシーの準備を行いました。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account AのアカウントID>:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
続いてaccount-b-role-1のAssumeRoleを許可するポリシーをアタッチしました。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<Account BのアカウントID>:role/account-b-role-1"
}
}
続いてAccount BでIAMロールの準備を行いました。信頼ポリシーのPrincipalにaccount-a-role-1を指定しました。(アタッチしたIAMポリシーは省略)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account AのアカウントID>:role/account-a-role-1"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
CloudShellの準備
今回はCloudShellを利用してAWSumeコマンドを実行していくため、CloudShellの準備も行いました。具体的には下記ファイルを作成しました。
[default]
region = ap-northeast-1
output = json
[profile account-a-role-1]
role_arn = arn:aws:iam::<Account AのアカウントID>:role/account-a-role-1
source_profile = default
[profile account-b-role-1]
role_arn = arn:aws:iam::<Account BのアカウントID>:role/account-b-role-1
source_profile = account-a-role-1
[default]
aws_access_key_id = <アクセスキーID>
aws_secret_access_key = <シークレットアクセスキー>
今回は便宜上IAMユーザーのアクセスキーID、シークレットアクセスキーを利用しました。
AWSumeのインストール
ここからAWSumeのインストールを行いました。CloudShellで下記を実行しました。
pip install awsume
awsumeをインストールできたことを確認しました。
また、コンソールログインを可能にするために、Awsume Console Pluginもインストールしました。それだけではうまく動作しなかったため、その他AWSumeのページに記載があったコマンドを実行しました。
pip install awsume-console-plugin
alias awsume=". awsume"
AWSUME_SKIP_ALIAS_SETUP=true pip install awsume
$ awsume-configure
===== Setting up bash =====
Wrote alias to /home/cloudshell-user/.bash_profile
Wrote autocomplete script to /home/cloudshell-user/.bash_profile
===== Setting up zsh =====
Wrote alias to /home/cloudshell-user/.zshenv
Wrote autocomplete script to /home/cloudshell-user/.zshenv
Wrote zsh function to /home/cloudshell-user/.awsume/zsh-autocomplete/_awsume
===== Finished setting up =====
ここまで完了したら、CloudShellを再起動しました。
ロールの連鎖を実施
AWSumeコマンドawsume <profile名>
でスイッチロールを実施し、aws sts get-caller-identiry
コマンドで呼び出し元認証情報を確認しました。
# スイッチロール前の呼び出し元認証情報を確認
$ aws sts get-caller-identity
{
"UserId": "<UserId>",
"Account": "<Account AのアカウントID>",
"Arn": "arn:aws:iam::<Account AのアカウントID>:user/<IAMユーザー名>"
}
# awsume <profile名>でスイッチロールを実行
$ awsume account-a-role-1
[account-a-role-1] Role credentials will expire 2024-07-13 14:00:48
# スイッチロール後の呼び出し元認証情報を確認
$ aws sts get-caller-identity
{
"UserId": "<論理Id>:account-a-role-1",
"Account": "<Account AのアカウントID>",
"Arn": "arn:aws:sts::<Account AのアカウントID>:assumed-role/account-a-role-1/account-a-role-1"
}
account-a-role-1にスイッチロールしたことを確認できました。
続いて、account-b-role-1にスイッチロールを実施し、先ほどインストールしたプラグインを使ってコンソールログインのためのURLを出力させました。
# account-b-role-1にスイッチロール -clオプションでコンソールのURLが標準出力された
$ awsume account-b-role-1 -cl
[account-a-role-1] Role credentials will expire 2024-07-13 14:20:34
[account-b-role-1] Role credentials will expire 2024-07-13 14:20:35
https://signin.aws.amazon.com/...<省略>
出力されたURLにアクセスすると、ログアウトを促すページが表示されました。
「ここをクリックしてください」を選択しました。
すると、Account Bのaccount-b-role-1にスイッチロールした状態でコンソール画面を開くことができました。
終わりに
AWSumeを使ってロールの連鎖を試してみました。ロールの連鎖は、とりあえず面白そうだからやってみたという記事が多い印象だったため、実際のユースケースがあるのだろうかと気になったので調べてみました。ユースケースについて気になる方は下記などを参照してみると良いかと思います。
参考記事