あめがえるのITブログ

頑張りすぎない。ほどほどに頑張るブログ。

【AWS】IAM Identity Centerのアカウントとユーザー/グループと許可セットの一覧を取得してみた


IAM Identity Centerのアカウントとユーザー/グループと許可セットの一覧をCLIで取得してcsvで出力してみた。※ほとんどChatGPTまかせ。。。

実践!

1.シェルスクリプト作成
1-1.AWS - CloudShell
1-2.下記を実行

$ vi sso.sh

1-3.下記を記載し保存
※viでshファイルを開いてコピペするとなぜか余計な文字が入ったので、、、一回$ vi sso.jsonとかで作成したあと、$ mv sso.json sso.shとかするとよかったです。
※INSERTモードに移動する際、「i」キーではなく、「:set paste」で入っても良いようでした。

#!/bin/bash

# 出力ファイル名
OUTPUT_FILE="user_group_assignments.csv"

# CSVのヘッダーを設定
echo "インスタンス,アカウント,ユーザー/グループ,許可セット" > $OUTPUT_FILE

# インスタンスリストを取得
INSTANCE_DETAILS=$(aws sso-admin list-instances --query "Instances[]" --output json)

# 各インスタンスの処理
for instance in $(echo "$INSTANCE_DETAILS" | jq -c ".[]"); do
  INSTANCE_ARN=$(echo $instance | jq -r ".InstanceArn")
  IDENTITY_STORE_ID=$(echo $instance | jq -r ".IdentityStoreId")

  echo "Processing Instance: $INSTANCE_ARN with Identity Store: $IDENTITY_STORE_ID"

  # 許可セットリストを取得
  PERMISSION_SET_ARNS=$(aws sso-admin list-permission-sets \
    --instance-arn $INSTANCE_ARN --query "PermissionSets[]" --output text)

  # アカウントとその割り当ての情報を収集する辞書を初期化
  declare -A ASSIGNMENTS_MAP

  # 各許可セットの処理
  for PERMISSION_SET_ARN in $PERMISSION_SET_ARNS; do
    # 許可セットの表示名を取得
    PERMISSION_SET_NAME=$(aws sso-admin describe-permission-set \
      --instance-arn $INSTANCE_ARN \
      --permission-set-arn $PERMISSION_SET_ARN \
      --query "PermissionSet.Name" --output text)

    echo "Processing Permission Set: $PERMISSION_SET_NAME ($PERMISSION_SET_ARN)"

    # 許可セットに紐づくアカウントリストを取得
    ACCOUNT_IDS=$(aws sso-admin list-accounts-for-provisioned-permission-set \
      --instance-arn $INSTANCE_ARN \
      --permission-set-arn $PERMISSION_SET_ARN \
      --query "AccountIds[]" --output text)

    # 各アカウントの処理
    for ACCOUNT_ID in $ACCOUNT_IDS; do
      echo "Processing Account: $ACCOUNT_ID"

      # アカウントに割り当てられたユーザーやグループを取得
      ASSIGNMENTS=$(aws sso-admin list-account-assignments \
        --instance-arn $INSTANCE_ARN \
        --account-id $ACCOUNT_ID \
        --permission-set-arn $PERMISSION_SET_ARN \
        --query "AccountAssignments[]" --output json)

      # JSONデータを解析してユーザー/グループを収集
      for assignment in $(echo $ASSIGNMENTS | jq -c ".[]"); do
        PRINCIPAL_ID=$(echo $assignment | jq -r ".PrincipalId")
        PRINCIPAL_TYPE=$(echo $assignment | jq -r ".PrincipalType")

        # ユーザーまたはグループの表示名を取得
        if [ "$PRINCIPAL_TYPE" == "USER" ]; then
          PRINCIPAL_NAME=$(aws identitystore describe-user \
            --identity-store-id $IDENTITY_STORE_ID \
            --user-id $PRINCIPAL_ID \
            --query "UserName" --output text)
        elif [ "$PRINCIPAL_TYPE" == "GROUP" ]; then
          PRINCIPAL_NAME=$(aws identitystore describe-group \
            --identity-store-id $IDENTITY_STORE_ID \
            --group-id $PRINCIPAL_ID \
            --query "DisplayName" --output text)
        else
          PRINCIPAL_NAME="Unknown"
        fi

        echo "Found Principal: $PRINCIPAL_NAME ($PRINCIPAL_TYPE) in Account: $ACCOUNT_ID"

        # ユーザー/グループごとに権限セットをまとめる
        KEY="${INSTANCE_ARN},${ACCOUNT_ID},${PRINCIPAL_NAME}"
        if [[ -z "${ASSIGNMENTS_MAP[$KEY]}" ]]; then
          ASSIGNMENTS_MAP[$KEY]="${PERMISSION_SET_NAME}"
        else
          ASSIGNMENTS_MAP[$KEY]+=",$PERMISSION_SET_NAME"
        fi
      done
    done
  done

  # 辞書の内容を確認
  echo "Contents of ASSIGNMENTS_MAP:"
  for KEY in "${!ASSIGNMENTS_MAP[@]}"; do
    echo "${KEY},${ASSIGNMENTS_MAP[$KEY]}"
  done

  # 統合された結果をCSVに書き込む
  for KEY in "${!ASSIGNMENTS_MAP[@]}"; do
    echo "${KEY},${ASSIGNMENTS_MAP[$KEY]}" >> $OUTPUT_FILE
    echo "Writing to CSV: ${KEY},${ASSIGNMENTS_MAP[$KEY]}"
  done

  # 一時的な辞書をクリア
  unset ASSIGNMENTS_MAP
done

# 完了メッセージ
echo "CSVファイルが作成されました: $OUTPUT_FILE"

1-4.シェル実行権限付与

$ chmod +x sso.sh

1-5.シェルスクリプト実行

$ ./sso.sh

 出力結果

$ ./sso.sh
Processing Instance: arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxxwith Identity Store: d-xxxxxxxxxx
Processing Permission Set: ReadOnlyAccess (arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxxx)
Processing Account: <アカウントID1>
Found Principal: test-group1 (GROUP) in Account: <アカウントID1>
Processing Permission Set: AdministratorAccess (arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxxx)
Processing Account: <アカウントID2>
Found Principal: test-group1 (GROUP) in Account: <アカウントID2>
Processing Account: <アカウントID1>
Found Principal: test-group1 (GROUP) in Account: <アカウントID1>
Processing Permission Set: SystemAdministrator (arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxxx)
Processing Account: <アカウントID1>
Found Principal: test-group1 (GROUP) in Account: <アカウントID1>
Contents of ASSIGNMENTS_MAP:
arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,<アカウントID1>,test-group1,ReadOnlyAccess,AdministratorAccess,SystemAdministrator
arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,<アカウントID2>,test-group1,AdministratorAccess
Writing to CSV: arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,<アカウントID1>,test-group1,ReadOnlyAccess,AdministratorAccess,SystemAdministrator
Writing to CSV: arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,<アカウントID2>,test-group1,AdministratorAccess
CSVファイルが作成されました: user_group_assignments.csv

1-6.中身確認

$ cat user_group_assignments.csv 

インスタンス,アカウント,ユーザー/グループ,許可セット
arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,<アカウントID1>,test-group1,ReadOnlyAccess,AdministratorAccess,SystemAdministrator
arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,<アカウントID2>,test-group1,AdministratorAccess


おまけ

1.標準出力版:

#!/bin/bash

# CSVの項目ヘッダーを標準出力
echo "インスタンス,アカウント,ユーザー/グループ,許可セット"

# インスタンスリストを取得
INSTANCE_DETAILS=$(aws sso-admin list-instances --query "Instances[]" --output json)

# 各インスタンスの処理
for instance in $(echo "$INSTANCE_DETAILS" | jq -c ".[]"); do
  INSTANCE_ARN=$(echo $instance | jq -r ".InstanceArn")
  IDENTITY_STORE_ID=$(echo $instance | jq -r ".IdentityStoreId")

  # 許可セットリストを取得
  PERMISSION_SET_ARNS=$(aws sso-admin list-permission-sets \
    --instance-arn $INSTANCE_ARN --query "PermissionSets[]" --output text)

  # アカウントとその割り当ての情報を収集する辞書を初期化
  declare -A ASSIGNMENTS_MAP

  # 各許可セットの処理
  for PERMISSION_SET_ARN in $PERMISSION_SET_ARNS; do
    # 許可セットの表示名を取得
    PERMISSION_SET_NAME=$(aws sso-admin describe-permission-set \
      --instance-arn $INSTANCE_ARN \
      --permission-set-arn $PERMISSION_SET_ARN \
      --query "PermissionSet.Name" --output text)

    # 許可セットに紐づくアカウントリストを取得
    ACCOUNT_IDS=$(aws sso-admin list-accounts-for-provisioned-permission-set \
      --instance-arn $INSTANCE_ARN \
      --permission-set-arn $PERMISSION_SET_ARN \
      --query "AccountIds[]" --output text)

    # 各アカウントの処理
    for ACCOUNT_ID in $ACCOUNT_IDS; do
      # アカウントに割り当てられたユーザーやグループを取得
      ASSIGNMENTS=$(aws sso-admin list-account-assignments \
        --instance-arn $INSTANCE_ARN \
        --account-id $ACCOUNT_ID \
        --permission-set-arn $PERMISSION_SET_ARN \
        --query "AccountAssignments[]" --output json)

      # JSONデータを解析してユーザー/グループを収集
      for assignment in $(echo $ASSIGNMENTS | jq -c ".[]"); do
        PRINCIPAL_ID=$(echo $assignment | jq -r ".PrincipalId")
        PRINCIPAL_TYPE=$(echo $assignment | jq -r ".PrincipalType")

        # ユーザーまたはグループの表示名を取得
        if [ "$PRINCIPAL_TYPE" == "USER" ]; then
          PRINCIPAL_NAME=$(aws identitystore describe-user \
            --identity-store-id $IDENTITY_STORE_ID \
            --user-id $PRINCIPAL_ID \
            --query "UserName" --output text)
        elif [ "$PRINCIPAL_TYPE" == "GROUP" ]; then
          PRINCIPAL_NAME=$(aws identitystore describe-group \
            --identity-store-id $IDENTITY_STORE_ID \
            --group-id $PRINCIPAL_ID \
            --query "DisplayName" --output text)
        else
          PRINCIPAL_NAME="Unknown"
        fi

        # ユーザー/グループごとに権限セットをまとめる
        KEY="${INSTANCE_ARN},${ACCOUNT_ID},${PRINCIPAL_NAME}"
        if [[ -z "${ASSIGNMENTS_MAP[$KEY]}" ]]; then
          ASSIGNMENTS_MAP[$KEY]="${PERMISSION_SET_NAME}"
        else
          ASSIGNMENTS_MAP[$KEY]+=",$PERMISSION_SET_NAME"
        fi
      done
    done
  done

  # 権限セットを標準出力に出力
  for KEY in "${!ASSIGNMENTS_MAP[@]}"; do
    echo "${KEY},${ASSIGNMENTS_MAP[$KEY]}"
  done

  # 一時的な辞書をクリア
  unset ASSIGNMENTS_MAP
done

 出力結果

$ ./sso.sh
インスタンス,アカウント,ユーザー/グループ,許可セット
arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,xxxxxxxxxxxx,test-group1,ReadOnlyAccess,AdministratorAccess,SystemAdministrator
arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,yyyyyyyyyyyy,test-group1,AdministratorAccess


2.標準出力且つ特定のアカウントのみ出力版:

#!/bin/bash

# 引数の確認
if [ $# -ne 1 ]; then
  echo "Usage: $0 <ACCOUNT_ID>"
  exit 1
fi

# 引数からアカウントIDを取得
TARGET_ACCOUNT_ID=$1

# CSVの項目ヘッダーを標準出力
echo "インスタンス,アカウント,ユーザー/グループ,許可セット"

# インスタンスリストを取得
INSTANCE_DETAILS=$(aws sso-admin list-instances --query "Instances[]" --output json)

# 各インスタンスの処理
for instance in $(echo "$INSTANCE_DETAILS" | jq -c ".[]"); do
  INSTANCE_ARN=$(echo $instance | jq -r ".InstanceArn")
  IDENTITY_STORE_ID=$(echo $instance | jq -r ".IdentityStoreId")

  # 許可セットリストを取得
  PERMISSION_SET_ARNS=$(aws sso-admin list-permission-sets \
    --instance-arn $INSTANCE_ARN --query "PermissionSets[]" --output text)

  # アカウントとその割り当ての情報を収集する辞書を初期化
  declare -A ASSIGNMENTS_MAP

  # 各許可セットの処理
  for PERMISSION_SET_ARN in $PERMISSION_SET_ARNS; do
    # 許可セットの表示名を取得
    PERMISSION_SET_NAME=$(aws sso-admin describe-permission-set \
      --instance-arn $INSTANCE_ARN \
      --permission-set-arn $PERMISSION_SET_ARN \
      --query "PermissionSet.Name" --output text)

    # 許可セットに紐づくアカウントリストを取得
    ACCOUNT_IDS=$(aws sso-admin list-accounts-for-provisioned-permission-set \
      --instance-arn $INSTANCE_ARN \
      --permission-set-arn $PERMISSION_SET_ARN \
      --query "AccountIds[]" --output text)

    # 各アカウントの処理
    for ACCOUNT_ID in $ACCOUNT_IDS; do
      # 指定されたアカウントID以外をスキップ
      if [[ "$ACCOUNT_ID" != "$TARGET_ACCOUNT_ID" ]]; then
        continue
      fi

      # アカウントに割り当てられたユーザーやグループを取得
      ASSIGNMENTS=$(aws sso-admin list-account-assignments \
        --instance-arn $INSTANCE_ARN \
        --account-id $ACCOUNT_ID \
        --permission-set-arn $PERMISSION_SET_ARN \
        --query "AccountAssignments[]" --output json)

      # JSONデータを解析してユーザー/グループを収集
      for assignment in $(echo $ASSIGNMENTS | jq -c ".[]"); do
        PRINCIPAL_ID=$(echo $assignment | jq -r ".PrincipalId")
        PRINCIPAL_TYPE=$(echo $assignment | jq -r ".PrincipalType")

        # ユーザーまたはグループの表示名を取得
        if [ "$PRINCIPAL_TYPE" == "USER" ]; then
          PRINCIPAL_NAME=$(aws identitystore describe-user \
            --identity-store-id $IDENTITY_STORE_ID \
            --user-id $PRINCIPAL_ID \
            --query "UserName" --output text)
        elif [ "$PRINCIPAL_TYPE" == "GROUP" ]; then
          PRINCIPAL_NAME=$(aws identitystore describe-group \
            --identity-store-id $IDENTITY_STORE_ID \
            --group-id $PRINCIPAL_ID \
            --query "DisplayName" --output text)
        else
          PRINCIPAL_NAME="Unknown"
        fi

        # ユーザー/グループごとに権限セットをまとめる
        KEY="${INSTANCE_ARN},${ACCOUNT_ID},${PRINCIPAL_NAME}"
        if [[ -z "${ASSIGNMENTS_MAP[$KEY]}" ]]; then
          ASSIGNMENTS_MAP[$KEY]="${PERMISSION_SET_NAME}"
        else
          ASSIGNMENTS_MAP[$KEY]+=",$PERMISSION_SET_NAME"
        fi
      done
    done
  done

  # 権限セットを標準出力に出力
  for KEY in "${!ASSIGNMENTS_MAP[@]}"; do
    echo "${KEY},${ASSIGNMENTS_MAP[$KEY]}"
  done

  # 一時的な辞書をクリア
  unset ASSIGNMENTS_MAP
done

 アカウントIDを引数に渡して実行

$ ./sso.sh <アカウントID>

 実行結果 例:

$ ./sso.sh 898xxxxxxxxx
インスタンス,アカウント,ユーザー/グループ,許可セット
arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx,898xxxxxxxxx,test-group1,ReadOnlyAccess,AdministratorAccess,SystemAdministrator



感想

ここまでしないと取れないものか、、、とはいえChatGPT優秀!