AWS CLIでSwitch Role してさらに Switch Role してみた。(ロールの連鎖:Role chaining)
福岡オフィスの梶原です。 先日、福岡オフィスでこんな会話がありました。
「スイッチロールしたいけどできないんですよね。」 「できるでしょ。」 「いや、正確にはユーザからはスイッチロールできるんですけど、スイッチロールしてからスイッチロールできなくて。」 「できないでしょ。スイッチロール元のユーザーで制限かかってるから」 「えー、そうなんですかー」 (わいがや) 「スイッチロール元を制限したいんですけど、それをロールにできないんですか?」 (わいがや) 「え、できた・・・CLIだけど」
ということで、調べたところこの動きは用語としては、ロールの連鎖
(Role chaining
)という動きみたいです。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-chaining
User1 に、RoleA および RoleB を引き受けるアクセス許可があるとします。さらに、RoleA には RoleB を引き受けるアクセス許可があるとします。AssumeRole API オペレーションで User1 の長期的なユーザー認証情報を使用して RoleA を引き受けることができます。このオペレーションは RoleA の短期的な認証情報を返します。ロールの連鎖を行うには、RoleA の短期認証情報を使用して RoleB を引き受けます。
図にするとこういう感じです。
ということで、
- User1で認証
-
User1からRoleAにスイッチロール
-
RoleAからRoleBにスイッチロール
をAWS CLIでやってみました。
いるもの
- User1 : AWS アカウント(要アクセスキー) ※(AWS 多要素認証 (MFA) で認証)非ルートユーザ
- RoleA : IAMロール(引き受け元User1)
- RoleB : IAMロール(引き受け元RoleA)
ポリシー設定
RoleAのポリシードキュメント
RoleAのポリシーでPrincipal(信頼されたエンティティ)にUser1を指定します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::YYYYYYYYYYYY:user/User1" }, "Action": "sts:AssumeRole", "Condition": { "Bool": { "aws:MultiFactorAuthPresent": "true" } } } ] }
※ログイン時MFAを有効に
RoleBのポリシードキュメント
RoleBのポリシーでPrincipal(信頼されたエンティティ)にRoleAを指定します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::XXXXXXXXXXXX:role/RoleA" }, "Action": "sts:AssumeRole", "Condition": {} } ] }
ポイントはPrincipalのrole/RoleA
の部分になります。
AWSのドキュメントによると保存時にプリンシパル ID に変換されます
ロールの Principal 要素に、特定の IAM ロールを指し示す ARN が含まれている場合、その ARN はポリシーを保存するときにロールの一意のプリンシパル ID に変換されます
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_principal.html
1. User1で認証
User1の認証情報設定
User1のアクセスキーID、シークレットアクセスキーをAWS CLIに設定します。
$ aws configure AWS Access Key ID [None]: HOGEHOGEHOGEHOGE AWS Secret Access Key [None]: FUGAFUGAFUGAFUGA Default region name [None]: ap-northeast-1 Default output format [None]:
~/.aws/credentials
ファイルが作成されているかと思います
$ cat ~/.aws/credentials [default] aws_access_key_id = HOGEHOGEHOGEHOGE aws_secret_access_key = FUGAFUGAFUGAFUGA
認証確認
$ aws sts get-caller-identity Enter MFA code for arn:aws:iam::YYYYYYYYYYYY:mfa/User1: { "UserId": "XXXXXXXXXXXXXXXXXXXXX", "Account": "YYYYYYYYYYYY", "Arn": "arn:aws:iam::YYYYYYYYYYYY:user/User1" } ※各値は環境によります
$ aws s3 ls Enter MFA code for arn:aws:iam::YYYYYYYYYYYY:mfa/User1: (S3へのアクセス権限があればバケットが表示されます)
2. スイッチロール1回目(User1 から RoleAへ)
.aws/configの設定
ロールの新しいプロファイル"role-a"
を .aws/config ファイルに設定します
[profile role-a] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleA mfa_serial = arn:aws:iam::YYYYYYYYYYYY:mfa/User1 source_profile = default
※ポリシーでAWS 多要素認証 (MFA) を必須にしていますのでmfa_serialを指定します
動作確認
AWS CLIのコマンド時profileオプションに"role-a"を指定します
$ aws sts get-caller-identity --profile role-a Enter MFA code for arn:aws:iam::YYYYYYYYYYYY:mfa/User1: { "UserId": "XXXXXXXXXXXXXXXXXXXXX:botocore-session-0123456789", "Account": "XXXXXXXXXXXX", "Arn": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/RoleA/botocore-session-0123456789" } ※各値は環境によります
$ aws s3 ls --profile role-a Enter MFA code for arn:aws:iam::YYYYYYYYYYYY:mfa/User1: (S3へのアクセス権限があればバケットが表示されます)
または
export AWS_PROFILE=role-a
を実施し、環境変数のAWS_PROFILEで、切り替えるプロファイルを指定してください。
3. スイッチロール2回目(User1 から RoleAから RoleBへ)
.aws/configの設定
ロールの新しいプロファイル"role-b"
を .aws/config ファイルに設定します
[profile role-a] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleA mfa_serial = arn:aws:iam::YYYYYYYYYYYY:mfa/User1 source_profile = default [profile role-b] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleB source_profile = role-a
ポイントはsource_profile = role-a
で、引き受け元のRoleAのプロファイルを指定します。
動作確認
AWS CLIのコマンド時profileオプションに"role-b"を指定します
$ aws sts get-caller-identity --profile role-b Enter MFA code for arn:aws:iam::YYYYYYYYYYYY:mfa/User1: { "UserId": "XXXXXXXXXXXXXXXXXXXXX:botocore-session-0123456789", "Account": "XXXXXXXXXXXX", "Arn": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/RoleB/botocore-session-0123456789" }
※各値は環境によります
$ aws s3 ls --profile role-b Enter MFA code for arn:aws:iam::YYYYYYYYYYYY:mfa/User1: (S3へのアクセス権限があればバケットが表示されます)
または
export AWS_PROFILE=role-b
を実施し、環境変数のAWS_PROFILEを指定してください。
補足 キャッシュされている認証情報の削除
どの認証情報を使っているかわからない。なんかキャッシュが効いているとわかりづらいとかあれば 以下コマンドでキャッシュを削除できます。
$ rm -r ~/.aws/cli/cache
まとめ
ユーザーからRoleにスイッチロールすることはよくあるのですが、RoleからRoleにスイッチロールする方法と指定の仕方はわかりにくかったので、まとめてみました。 使い方によっては、踏み台Roleみたいにできるかもしれません(通常は別の方法で制限することをおすすめします) また、CLIからは使えますので、CloudFormationの実行などで使える場面もあるかと思います。 尚、AWSコンソールからのロールからロールへの切り替えは現在のところ元の認証情報を使用するためできないようです。
おまけ
「ロールからスイッチロールできたけど、どこまでいけるんでしょうか?」 「え?なにが?」 「chaining」(なんか発音いいな。) 「・・・」
[profile role-a] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleA mfa_serial = arn:aws:iam::XXXXXXXXXXXX:mfa/User1 source_profile = default [profile role-b] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleB source_profile = role-a [profile role-c] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleC source_profile = role-b [profile role-d] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleD source_profile = role-c [profile role-e] role_arn = arn:aws:iam::XXXXXXXXXXXX:role/RoleE source_profile = role-d
$ aws sts get-caller-identity --profile role-e { "UserId": "XXXXXXXXXXXX:botocore-session-1234567890", "Account": "XXXXXXXXXXXX", "Arn": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/RoleE/botocore-session-1234567890" }
「スイッチロール5回まではいけました。これ以上は怒られそうなのでやめときます。」
「Let's Loop!」 (ちょ発音w) 「(ざわざわ)」
やり方は記載しませんが、中でちゃんと連鎖をスタックにつんで管理しているようで、ループするように設定したらエラーとなりました。
--debug
などを指定してAWS CLIを実行してみると動きがわかって面白いです!すばらっ
参考URL
IAM JSON ポリシーの要素:Principal https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_principal.html
AWS CLI の設定 » IAM ロールを引き受ける https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-role.html