AWSの組織(Organizations)でIAM Access Analyzer の未使用の許可のスキャン対象となるユーザーとロールを算出してみた
IAM Access Analyzer で未使用のアクセス権を組織(Organizations)全体で検出してみた の際に、実際にどれくらい料金がかかるか不安だったので試算してみました。
スキャン対象となるIAMユーザー、ロールの算出
AWS Resouce Explore を使う方法
対象となるユーザまたロールが1000件以下であれば、
AWS Organizationsにて、マルチアカウントのView(インデクス)が作成されていれば、AWS Resource Explorer から対象となる IAMユーザ、またIAMロールは簡単に検出できます。
以下の検索文でResouce Exploreにて対象となるIAMユーザ、IAMロールを抽出してください
AWS Resource Explorer > リソースの検索
https://resource-explorer.console.aws.amazon.com/resource-explorer/home?region=ap-northeast-1#/search
必要に応じて、「ビューを変更」を選択して、AWS Organizations全体のビュー(マルチアカウントビュー)を選択します
マルチアカウントのビューの作成方法はこちらの記事をご参考ください https://dev.classmethod.jp/articles/aws-resource-explorer-multi-account-view/
IAMロールを検索
検索クエリに resourcetype:iam:role
を入力し、検索してください
IAMユーザーを検索
検索クエリに resourcetype:iam:user
を入力し、検索してください
リソース数に抽出されたリソースの件数が表示されます。
なお、AWS Resource Explorerの制限により検索結果が1000件を超える場合は、総数は算出できませんのでご注意ください。 その際は以下でご案内する 各アカウントにスイッチロールをして総数を算出する方法をご参考にしてください
各アカウントにスイッチロールをして総数を算出する方法
管理アカウントより各アカウントにAWSControlTowerExecution もしくは、OrganizationAccountAccessRoleへスイッチロールを行い、ユーザーとロールの総数を算出してみます。 サンプルシェルスクリプトを作成したので、ご活用ください。
なお、アカウント内にOrganizationAccountAccessRole がない場合は、StackSetsなどを利用して、対象のアカウントにロールを作成してロール名を変更してください。
管理アカウントにログインしCloudShellより実行を行います。
シェルの中身は
- 組織内のアカウント一覧を取得
- アカウントごとにIAMユーザーとIAMロールの数を集計
- AWSControlTowerExecutionにスイッチロール
- スイッチロールに失敗した場合(Control Tower 有効化済みでない場合)OrganizationAccountAccessRoleを使用します。
- IAMユーザーとIAMロールの数を取得
- AWSControlTowerExecutionにスイッチロール
- 組織全体のIAMユーザーとIAMロールの合計を表示
- アカウントの総数を表示
- アカウントのIAMユーザー数とIAMロールの平均を計算して表示
となります
シェルスクリプト
#!/bin/bash # 組織内のアカウント一覧を取得 account_list=$(aws organizations list-accounts --output json | jq -r '.Accounts[] | .Id') # 組織全体のIAMユーザーとIAMロールの数を初期化 total_users_count=0 total_roles_count=0 account_count=0 # アカウントごとにIAMユーザーとIAMロールの数を集計 for account_id in $account_list do # 環境変数をクリア unset AWS_ACCESS_KEY_ID unset AWS_SECRET_ACCESS_KEY unset AWS_SESSION_TOKEN echo "Account ID: $account_id" # アカウント名を取得 account_name=$(aws organizations describe-account --account-id $account_id --output json | jq -r '.Account.Name') echo "Account Name: $account_name" # AWSControlTowerExecutionにスイッチロール role_session_name="tempSession" credentials=$(aws sts assume-role --role-arn arn:aws:iam::$account_id:role/AWSControlTowerExecution --role-session-name $role_session_name 2>&1) if [ $? -ne 0 ]; then echo "AWSControlTowerExecutionへのAssumeRoleに失敗しました。OrganizationAccountAccessRoleを使用します。" role_session_name="tempSession" role_name="OrganizationAccountAccessRole" role_arn="arn:aws:iam::$account_id:role/$role_name" credentials=$(aws sts assume-role --role-arn $role_arn --role-session-name $role_session_name) fi export AWS_ACCESS_KEY_ID=$(echo $credentials | jq -r '.Credentials.AccessKeyId') export AWS_SECRET_ACCESS_KEY=$(echo $credentials | jq -r '.Credentials.SecretAccessKey') export AWS_SESSION_TOKEN=$(echo $credentials | jq -r '.Credentials.SessionToken') # IAMユーザーとIAMロールの数を取得 users_count=$(aws iam list-users --output json | jq '.Users | length') roles_count=$(aws iam list-roles --output json | jq '.Roles | length') echo "IAMユーザーの数: $users_count" echo "IAMロールの数: $roles_count" # 組織全体の合計に加算 total_users_count=$((total_users_count + users_count)) total_roles_count=$((total_roles_count + roles_count)) account_count=$((account_count + 1)) done # 組織全体のIAMユーザーとIAMロールの合計を表示 echo "組織全体のIAMユーザーの合計: $total_users_count" echo "組織全体のIAMロールの合計: $total_roles_count" # アカウントの総数を表示 echo "アカウントの総数: $account_count" # 平均を計算して表示 average_users_count=$((total_users_count / account_count)) average_roles_count=$((total_roles_count / account_count)) echo "組織全体のIAMユーザーの平均: $average_users_count" echo "組織全体のIAMロールの平均: $average_roles_count"
シェルスクリプト(各アカウントに1000件以上のユーザー、ロールがある場合)
1000件のページネーションを行うようにしています。
#!/bin/bash # 組織内のアカウント一覧を取得 account_list=$(aws organizations list-accounts --output json | jq -r '.Accounts[] | .Id') # 組織全体のIAMユーザーとIAMロールの数を初期化 total_users_count=0 total_roles_count=0 account_count=0 # アカウントごとにIAMユーザーとIAMロールの数を集計 for account_id in $account_list do # 環境変数をクリア unset AWS_ACCESS_KEY_ID unset AWS_SECRET_ACCESS_KEY unset AWS_SESSION_TOKEN echo "Account ID: $account_id" # アカウント名を取得 account_name=$(aws organizations describe-account --account-id $account_id --output json | jq -r '.Account.Name') echo "Account Name: $account_name" # AWSControlTowerExecutionにスイッチロール role_session_name="tempSession" credentials=$(aws sts assume-role --role-arn arn:aws:iam::$account_id:role/AWSControlTowerExecution --role-session-name $role_session_name 2>&1) if [ $? -ne 0 ]; then echo "AWSControlTowerExecutionへのAssumeRoleに失敗しました。OrganizationAccountAccessRoleを使用します。" role_session_name="tempSession" role_name="OrganizationAccountAccessRole" role_arn="arn:aws:iam::$account_id:role/$role_name" credentials=$(aws sts assume-role --role-arn $role_arn --role-session-name $role_session_name) fi export AWS_ACCESS_KEY_ID=$(echo $credentials | jq -r '.Credentials.AccessKeyId') export AWS_SECRET_ACCESS_KEY=$(echo $credentials | jq -r '.Credentials.SecretAccessKey') export AWS_SESSION_TOKEN=$(echo $credentials | jq -r '.Credentials.SessionToken') # ページネーション処理を含めてIAMユーザーとIAMロールの数を取得 users_count=0 next_token="" while true; do response=$(aws iam list-users --output json --max-items 1000 $([ -n "$next_token" ] && echo "--starting-token $next_token")) users_count=$((users_count + $(echo $response | jq '.Users | length'))) next_token=$(echo $response | jq -r '.NextToken') [ "$next_token" = "null" ] && break done roles_count=0 next_token="" while true; do response=$(aws iam list-roles --output json --max-items 1000 $([ -n "$next_token" ] && echo "--starting-token $next_token")) roles_count=$((roles_count + $(echo $response | jq '.Roles | length'))) next_token=$(echo $response | jq -r '.NextToken') [ "$next_token" = "null" ] && break done echo "IAMユーザーの数: $users_count" echo "IAMロールの数: $roles_count" # 組織全体の合計に加算 total_users_count=$((total_users_count + users_count)) total_roles_count=$((total_roles_count + roles_count)) account_count=$((account_count + 1)) done # 組織全体のIAMユーザーとIAMロールの合計を表示 echo "組織全体のIAMユーザーの合計: $total_users_count" echo "組織全体のIAMロールの合計: $total_roles_count" # アカウントの総数を表示 echo "アカウントの総数: $account_count" # 平均を計算して表示 average_users_count=$((total_users_count / account_count)) average_roles_count=$((total_roles_count / account_count)) echo "組織全体のIAMユーザーの平均: $average_users_count" echo "組織全体のIAMロールの平均: $average_roles_count"
実行結果
Account ID: XXXXXXXXXXXX Account Name: Acount XXXXXXXXXXXX AWSControlTowerExecutionへのAssumeRoleに失敗しました。OrganizationAccountAccessRoleを使用します。 An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/AWSReservedSSO_AWSAdministratorAccess_xxxx is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::XXXXXXXXXXXX:role/OrganizationAccountAccessRole IAMユーザーの数: 0 IAMロールの数: NN Account ID: AAAAAAAAAAAA Account Name: Acount AAAAAAAAAAAA IAMユーザーの数: 0 IAMロールの数: NN Account ID: BBBBBBBBBBBB Account Name: Acount BBBBBBBBBBBB IAMユーザーの数: 2 IAMロールの数: NN Account ID: CCCCCCCCCCCC Account Name: Acount CCCCCCCCCCCC IAMユーザーの数: 0 IAMロールの数: NN 組織全体のIAMユーザーの合計: 2 組織全体のIAMロールの合計: NNN アカウントの総数: 4 組織全体のIAMユーザーの平均: 0 組織全体のIAMロールの平均: AVG
※組織全体のアカウントで動かしているので、管理アカウント自体の場合はスイッチロールに失敗していますが、シェルを実行している際の権限を使用します。
現時点(2024/02)では、以下の料金表により 0.20USD x 分析された IAM ロールまたはユーザー/月となります。
0.20USD x 分析された IAM ロールまたはユーザー/月
AWS Pricing Calculator で試算する
なお、月あたりの試算はAWS Pricing Calculator でも計算できますので、ご参考ください
https://calculator.aws/#/createCalculator/IAMAccessAnalyzer
スキャン対象のアカウント数、平均ロール数、平均ユーザー数を入力して計算します。 トータルコストの欄に試算額が表示されます。
参考
AWS Identity and Access Management Access Analyzer の結果の使用開始
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-getting-started.html
https://dev.classmethod.jp/articles/script-to-create-delete-all-regions-of-iam-access-analyzer/