はじめに
前回は、下記記事で、単一のAWSアカウントの情報をSteampipeで可視化するやり方を記載したので、今度はOrganization配下にある子アカウントの各種情報をとってくる内容について、書いていこうと思います。
【今回やること】
1.Organization配下の踏み台AWSアカウントにsso loginし、それを経由してアクセス先のAWSアカウントにアクセスできるように定義する
2.Steampipeで、各子アカウントの情報を取得する。
前提条件
- 下記記事の記載内容がセットアップ済みであること
- 今回の実行を想定した環境は、下記のとおりである
アカウント種別 | AWSアカウントID |
---|---|
Organization配下の踏み台AWSアカウント | 111111111111 |
情報取得先のAWSアカウント① | 222222222222 |
情報取得先のAWSアカウント② | 333333333333 |
- ssp loginする際は、「https://XXXXXXXX.awsapps.com/start/」 のURLを知っている且つ、踏み台AWSアカウントにアクセス権があるユーザで作業をおこなう。
手順
(1)権限設定周りの事前作業
1.IAM Identity Centerで、今回対応する用に、下記のインラインポリシーをアタッチした許可セットを作成し、Organization配下の踏み台AWSアカウントに権限割り当てをおこなう
※Permission Set を AWSアカウントに割り当てると、それ用のIAM Roleが自動生成されるので、今回はそれを活用する為、アカウントへの割り当てまでをおこなう。
※ここで作成する許可セット名は「AssumeIntoChildAccountsRole」とする。(後続手順で指定する)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAssumeIntoMultiAccounts",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::222222222222:role/CrossAccount-TargetRole",
"arn:aws:iam::333333333333:role/CrossAccount-TargetRole"
]
}
]
}
2.情報取得先のAWSアカウントで、下記のymlをデプロイし、IAMロールを作成する。
今回のデプロイ先は、222222222222,333333333333とする。
※「TrustedRoleArn」で指定しているArnは、手順1で自動生成されたIAM RoleのArnを指定する。
AWSTemplateFormatVersion: '2010-09-09'
Description: >
Creates a custom role in THIS account that trusts a role in ANOTHER account.
Parameters:
TrustedRoleArn:
Type: String
Description: ARN of the source role allowed to assume this role (from the other AWS account).
Default: arn:aws:iam::111111111111:role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_XXXXXXXXXXXXXXXXXX
RoleName:
Type: String
Default: CrossAccount-TargetRole
Description: Name of the role to create in this (target) account.
ManagedPolicyArns:
Type: List<String>
Default: arn:aws:iam::aws:policy/ReadOnlyAccess
Description: >
AWS managed or customer managed policy ARNs to attach to the role.
MaxSessionDurationSeconds:
Type: Number
Default: 3600
AllowedValues: [900, 3600, 43200]
Description: Max session duration for the role in seconds (15m, 1h, or 12h).
Resources:
CrossAccountRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref RoleName
MaxSessionDuration: !Ref MaxSessionDurationSeconds
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: TrustExternalSSORole
Effect: Allow
Principal:
AWS: !Ref TrustedRoleArn
Action:
- sts:AssumeRole
- sts:TagSession
ManagedPolicyArns: !Ref ManagedPolicyArns
Outputs:
RoleArn:
Description: ARN of the created cross-account role.
Value: !GetAtt CrossAccountRole.Arn
RoleName:
Description: Name of the created role.
Value: !Ref CrossAccountRole
(2)OS側の作業
1.AWS構成ファイルの生成
※今回の想定では、Organization配下の踏み台サーバに、aws sso loginでアクセスし、クロスアカウントアクセスで「222222222222」「333333333333」もアクセスできるようにするものです。
[sso-session my-sso]
sso_start_url = https://XXXXXXXX.awsapps.com/start/
sso_region = ap-northeast-1
[profile org-bastion]
sso_session = my-sso
sso_account_id = 111111111111
sso_role_name = AssumeIntoChildAccountsRole
region = ap-northeast-1
[profile test1]
source_profile = org-bastion
role_arn = arn:aws:iam::222222222222:role/CrossAccount-TargetRole
region = ap-northeast-1
[profile test2]
source_profile = org-bastion
role_arn = arn:aws:iam::333333333333:role/CrossAccount-TargetRole
region = ap-northeast-1
2.AWS CLIで、SSOログインをおこなう
※プロファイル「org-bastion」を指定し、SSOログインし、対象のAWSアカウントにログインする。
[ec2-user@ip-10-192-0-236 ~]$ aws sso login --profile org-bastion --use-device-code
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
https://XXXXXXXXXX.awsapps.com/start/#/device
Then enter the code:
AAAA-BBBB
↓認証が通ると下記の出力がでる
Successfully logged into Start URL: https://XXXXXXXXXX.awsapps.com/start
指定されたURLをブラウザで開くと、下記の画面が表示されますので、出力されたコードを入力し、「確認して続行」をクリックする
↓アクセスを許可するかの確認画面で、「許可」をクリックする
↓認証が通ると下記の画面になる。
3.下記のコマンドを実行し、sso login 後のログイン後の確認をおこなう
[ec2-user@ip-10-192-0-14 ~]$ aws sts get-caller-identity --profile org-bastion
[ec2-user@ip-10-192-0-14 ~]$ aws sts get-caller-identity --profile test1
[ec2-user@ip-10-192-0-14 ~]$ aws sts get-caller-identity --profile test2
4.現在ログインしている認証ファイルのセッションの終了時間(有効期限)を確認する
・ファイル名を確認する
[ec2-user@ip-10-192-0-14 ~]$ ll ~/.aws/sso/cache/
total 8
-rw-------. 1 ec2-user ec2-user 2256 Sep 8 08:40 botocore-client-id-xxxxxxxxxxxxxxxxxxxxxxxxxx.json
-rw-------. 1 ec2-user ec2-user 1873 Sep 5 09:12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.json
・「botocore-client-id-xxxx.json」形式のファイルをJSON形式を指定し、出力する。(ファイル名は各環境によって異なります。)
[ec2-user@ip-10-192-0-14 ~]$ cat ~/.aws/sso/cache/botocore-client-id-xxxxxxxxxxxxxxxxxxxxxxxxxx.json | jq .
{
"startUrl": "https://xxxxxxxxx.awsapps.com/start",
"region": "ap-northeast-1",
"accessToken": "aaaaaaaaa....",
"expiresAt": "2025-09-08T16:40:05Z",
"clientId": "aaaaaaaaa",
"clientSecret": "xxxxxxx..."
}
↑上記で出力された「expiresAt」がセッションの有効期限で、UTC時刻で記載されてます。
6.一時クレデンシャル発効後のCLI実行確認
※ここで、S3バケット名が帰ってくればOK。
[ec2-user@ip-10-192-0-230 ~]$ aws s3 ls --profile test1
7.Steampipeの定義ファイルで、Organization配下のアカウントにアクセスできるように書き換える
※ここでは、踏み台サーバの定義は省略してOK
# test1
connection "aws_test1" {
plugin = "aws"
profile = "tes1"
regions = ["ap-northeast-1", "us-east-1"]
}
# test2
connection "aws_test2" {
plugin = "aws"
profile = "tes2"
regions = ["ap-northeast-1", "us-east-1"]
}
# ALL
connection "aws_all_targets" {
plugin = "aws"
type = "aggregator"
connections = ["aws_test1", "aws_test2"]
}
8.クエリの実行確認
※Fromで指定するテーブル名は、[aws.spcファイルで定義したconnection名].[テーブル名]でconnectionを指定して情報を取得するに定義してます。
注意点
[connection名].[テーブル名]形式を指定せずに実行した際は、aws.spcファイルで定義したconnection名のアルファベット順で一番先頭にマッチしたコンディション情報をとってくる動きになる為、予期せぬ動作が起こりやすいです。なので、基本的には、[connection名].[テーブル名]の形式を必ず指定する運用が好ましです。
上記例では、「aws_all_targets」がデフォルトコンディションとして選ばれる。
[ec2-user@ip-10-192-0-230 ~]$ steampipe query
・aws_test1のVPC情報
select
account_id,
tags ->> 'Name' as name,
region,
vpc_id,
cidr_block,
dhcp_options_id,
is_default
from
aws_test1.aws_vpc ;
・aws_test2のVPC情報
select
account_id,
tags ->> 'Name' as name,
region,
vpc_id,
cidr_block,
dhcp_options_id,
is_default
from
aws_test2.aws_vpc ;
「~/.aws/config」と「~/.steampipe/config/aws.spc」の連携がうまくいっているかの確認は、下記のクエリを実行すればよい。ここで、aws.spcで定義したコンディション名が表示されていればOK
> select name, plugin, file_name from steampipe_connection order by name;
+--------------------------------+--------------------------------------------------+------------------------------------------------+
| name | plugin | file_name |
+--------------------------------+--------------------------------------------------+------------------------------------------------+
| aws_all_targets | hub.steampipe.io/plugins/turbot/aws@latest | /home/ec2-user/.steampipe/config/aws.spc |
| aws_test1 | hub.steampipe.io/plugins/turbot/aws@latest | /home/ec2-user/.steampipe/config/aws.spc |
| aws_test2 | hub.steampipe.io/plugins/turbot/aws@latest | /home/ec2-user/.steampipe/config/aws.spc |
| steampipe | hub.steampipe.io/plugins/turbot/steampipe@latest | /home/ec2-user/.steampipe/config/steampipe.spc |
+--------------------------------+--------------------------------------------------+------------------------------------------------+
最後に
今回は、ダッシュボードの作成は省略するが、前回作ったようにダッシュボード生成用の定義ファイルを作成すれば、マルチアカウント管理のダッシュボードが完成します。
この投稿が誰かのお役に立てば幸いです。