Organizations 統合 GuardDuty 有効化前の既存環境影響一括調査

Organizations 統合 GuardDuty 有効化前の既存環境影響一括調査

2025.07.28

こんにちは!コンサルティング部のくろすけです!

AWS Organizations (以降 Organizations ) 統合の Amazon GuardDuty (以降 GuardDuty ) の有効化の際に、既存の GuardDuty の設定状況を確認したい場合があると思います。
そこで、AWS Config Aggregator (以降 Aggregator ) を活用した効率的な調査方法を検証してみました!

この記事では、Aggregator 機能を使って組織全体の GuardDuty 設定を一括で調査する方法をご紹介します。

目次

概要

調査の背景

Organizations 統合の GuardDuty 有効化において、以下のような課題があるかと思います

  • 組織内の全アカウント・リージョンの GuardDuty 設定状況を把握したい
  • 各保護機能(S3 Protection、Malware Protection等)の有効化状況を一覧化したい
  • 手動での確認は非効率的で、設定状況を一覧で確認したい

料金

現在(2025/07/28)時点で Aggregator 自体には料金がかかりません。
ただし、必ず最新情報をご確認ください。

https://repost.aws/questions/QUAwnwgklDQW-dpkuqSzwWsg/aws-config-aggregator-cost
https://aws.amazon.com/jp/config/pricing/

調査対象と条件

検出対象

  • 組織内の全てのアカウントおよびリージョンの GuardDuty(管理アカウント含む)

検出条件

  • Organizations 管理下のアカウントであること
    • 管理アカウント、メンバーアカウント双方検出可能
  • メンバーアカウントは、Control Tower 管理外であること
    • 特にリージョン拒否設定の影響を受け、正しくリソースが取得できない可能性有
  • Config が有効であること
  • Config が GuardDuty Detector リソースを記録していること

出力項目

  • AccountId:アカウントID
  • AccountName:アカウント名
  • Region:リージョン
  • RegionStatus:リージョンの有効化状況
  • ConfigStatus:Config の有効化状況
  • ConfigRecorderGuardDutyStatus:Config の GuardDuty 記録状況
  • GuardDutyDetectorId:GuardDuty Detector のリソースID
  • GuardDutyStatus:GuardDuty の有効化状況
  • GuardDutyCreatedAt:GuardDuty の作成日
  • FindingPublishingFrequency:GuardDuty の結果更新頻度
  • S3Protection:GuardDuty 保護プラン(S3Protection)の有効化状況
  • EKSProtection:GuardDuty 保護プラン(EKSProtection)の有効化状況
  • MalwareProtectionForEC2:GuardDuty 保護プラン(MalwareProtectionForEC2)の有効化状況
  • RDSProtection:GuardDuty 保護プラン(RDSProtection)の有効化状況
  • RuntimeMonitoring:GuardDuty 保護プラン(RuntimeMonitoring)の有効化状況
  • LambdaProtection:GuardDuty 保護プラン(LambdaProtection)の有効化状況
  • CheckTime:確認日時

やってみた

事前準備

1. AWS Account Management の信頼されたアクセスの有効化(実行アカウント:管理アカウント)

1-1. AWS Account Management の信頼されたアクセスの確認
下記のコマンドを実行し、 ServicePrincipalaccount.amazonaws.com が存在するか確認

aws organizations list-aws-service-access-for-organization --output table

1-2. AWS Account Management の信頼されたアクセスの有効化

aws organizations enable-aws-service-access \
	--service-principal account.amazonaws.com

1-3. AWS Account Management の信頼されたアクセスの確認
下記のコマンドを実行し、 ServicePrincipalaccount.amazonaws.com が存在することを確認

aws organizations list-aws-service-access-for-organization --output table

2. AWS Config の委任管理アカウントの登録(実行アカウント:管理アカウント)

2-1. AWS Config の信頼されたアクセスの確認
下記のコマンドを実行し、 ServicePrincipalconfig.amazonaws.com および config-multiaccountsetup.amazonaws.com が存在するか確認

aws organizations list-aws-service-access-for-organization --output table

2-2. AWS Config の信頼されたアクセスの有効化
ServicePrincipalconfig.amazonaws.comが存在しない場合は下記を実行

aws organizations enable-aws-service-access \
	--service-principal=config.amazonaws.com

ServicePrincipalconfig-multiaccountsetup.amazonaws.comが存在しない場合、下記を実行

aws organizations enable-aws-service-access \
	--service-principal=config-multiaccountsetup.amazonaws.com

2-3. AWS Account Management の信頼されたアクセスの確認
下記のコマンドを実行し、 ServicePrincipalconfig.amazonaws.com および config-multiaccountsetup.amazonaws.com が存在することを確認

aws organizations list-aws-service-access-for-organization --output table

2-4. AWS Config の委任管理アカウントの登録

aws organizations register-delegated-administrator \
	--service-principal=config.amazonaws.com \
	--account-id "${DelegatedAdministratorAccountID}"

aws organizations register-delegated-administrator \
	--service-principal=config-multiaccountsetup.amazonaws.com \
	--account-id "${DelegatedAdministratorAccountID}"

2-5. AWS Config の委任管理アカウントの登録確認

aws organizations list-delegated-administrators --output table \
	--service-principal=config.amazonaws.com

aws organizations list-delegated-administrators --output table \
	--service-principal=config-multiaccountsetup.amazonaws.com

3. AWS Config Aggregator 用 IAMロール の作成(実行アカウント:委任管理アカウント)

3-1. IAMロール 作成

aws iam create-role --role-name OrgConfigAggregatorRole \
	--assume-role-policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"config.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}" \
	--description "Role for organizational AWS Config aggregator"

3-2. IAMロール にポリシーをアタッチ

aws iam attach-role-policy \
	--role-name OrgConfigAggregatorRole \
	--policy-arn "arn:aws:iam::aws:policy/service-role/AWSConfigRoleForOrganizations"

3-3. IAMロール および ポリシー の状況確認

aws iam list-attached-role-policies \
	--role-name OrgConfigAggregatorRole

4. AWS Config Aggregator の作成(実行アカウント:委任管理アカウント)

4-1. IAMロール ARN の取得および AWS Config Aggregator の作成

org_config_role_arn=$(aws iam get-role --output text \
	--role-name OrgConfigAggregatorRole --query "Role.Arn")

aws configservice put-configuration-aggregator \
	--configuration-aggregator-name OrgConfigAggregator \
	--organization-aggregation-source "{\"RoleArn\": \"${org_config_role_arn}\",\"AllAwsRegions\": true}"

4-2. AWS Config Aggregator の作成確認

aws configservice describe-configuration-aggregators \
	--configuration-aggregator-names OrgConfigAggregator

GuardDutyの設定状況の取得

GuardDuty の有効化および設定状況を取得するスクリプトを下記に記載します。
ただしこのスクリプトで検出可能な GuardDuty は下記になります。

検出スクリプト概要

検出対象

  • 組織内の全てのアカウントおよびリージョンの GuardDuty (管理アカウント含む)

検出条件
以下は GuardDuty の設定状況が正確に取得できる場合の条件です。
ただし設定状況が取得できない場合は、出力結果より原因を絞り込むことが可能です。

  • Organizations 管理下のアカウントであること
    • 管理アカウント、メンバーアカウント双方検出可能
  • メンバーアカウントは、Control Tower 管理外であること
    • 特にリージョン拒否設定の影響を受け、正しくリソースが取得できない可能性有
  • AWS Config が有効であること
  • AWS Config が GuardDuty Detector リソースを記録していること

出力項目

  • AccountId:アカウントID
  • AccountName:アカウント名
  • Region:リージョン
  • RegionStatus:リージョンの有効化状況
  • ConfigStatus:Config の有効化状況
  • ConfigRecorderGuardDutyStatus:Config の GuardDuty 記録状況
  • GuardDutyDetectorId:GuardDuty Detector のリソースID
  • GuardDutyStatus:GuardDuty の有効化状況
  • GuardDutyCreatedAt:GuardDuty の作成日
  • FindingPublishingFrequency:GuardDuty の結果更新頻度
  • S3Protection:GuardDuty 保護プラン(S3Protection)の有効化状況
  • EKSProtection:GuardDuty 保護プラン(EKSProtection)の有効化状況
  • MalwareProtectionForEC2:GuardDuty 保護プラン(MalwareProtectionForEC2)の有効化状況
  • RDSProtection:GuardDuty 保護プラン(RDSProtection)の有効化状況
  • RuntimeMonitoring:GuardDuty 保護プラン(RuntimeMonitoring)の有効化状況
  • LambdaProtection:GuardDuty 保護プラン(LambdaProtection)の有効化状況
  • CheckTime:確認日時

アカウントおよびリージョン情報取得(実行アカウント:管理アカウント)
下記のシェルスクリプトを実行することで、アカウントおよびリージョンの有効化状況を取得
情報はCSVで出力され、CSVを次のシェルスクリプトの入力として使用

#!/bin/bash

# =============================================================================
# 組織内アカウント・リージョン有効化状況確認スクリプト
# =============================================================================
# 説明: 組織内の全アカウント・リージョンの有効化状況を確認してCSVで出力する
# 実行環境: 管理アカウントまたは委任管理アカウントのCloudShell
# 必要権限: Organizations, Account の読み取り権限
# =============================================================================

set -euo pipefail

# 定数定義
readonly SCRIPT_NAME="$(basename "$0")"
readonly OUTPUT_FILE="account_region_status_$(date +%Y%m%d_%H%M%S).csv"

# ログ関数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}

error_log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $*" >&2
}

# 使用法表示
usage() {
    cat << EOF
使用法: $SCRIPT_NAME [OPTIONS]

組織内アカウント・リージョン有効化状況確認スクリプト

OPTIONS:
    -h, --help              このヘルプを表示
    -o, --output FILE       出力ファイル名を指定 (デフォルト: $OUTPUT_FILE)
    -r, --regions LIST     リージョンリストを指定 (コンマ区切り、デフォルト: 全リージョン)
    --dry-run              実際のチェックを行わずに設定を表示

例:
    $SCRIPT_NAME
    $SCRIPT_NAME -o my_output.csv
    $SCRIPT_NAME -r us-east-1,ap-northeast-1
    $SCRIPT_NAME --dry-run
EOF
}

# 引数解析
parse_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                usage
                exit 0
                ;;
            -o|--output)
                OUTPUT_FILE="$2"
                shift 2
                ;;
            -r|--regions)
                REGIONS="$2"
                shift 2
                ;;
            --dry-run)
                DRY_RUN=true
                shift
                ;;
            *)
                error_log "不明なオプション: $1"
                usage
                exit 1
                ;;
        esac
    done
}

# 前提条件チェック
check_prerequisites() {
    log "前提条件をチェック中..."

    # AWS CLIの確認
    if ! command -v aws &> /dev/null; then
        error_log "AWS CLI がインストールされていません"
        exit 1
    fi

    # AWS認証情報の確認
    if ! aws sts get-caller-identity &> /dev/null; then
        error_log "AWS認証情報が設定されていません"
        exit 1
    fi

    # 組織アカウントかどうかの確認
    if ! aws organizations describe-organization &> /dev/null; then
        error_log "組織の管理アカウントまたは委任管理アカウントで実行してください"
        exit 1
    fi

    log "前提条件チェック完了"
}

# 組織アカウント一覧取得
get_organization_accounts() {
    local accounts
    accounts=$(aws organizations list-accounts \
        --query 'Accounts[?Status==`ACTIVE`].[Id,Name]' \
        --output text 2>/dev/null || echo "")

    if [[ -z "$accounts" ]]; then
        return 1
    fi

    # 空行を除去してから正確な行数をカウント
    accounts=$(echo "$accounts" | sed '/^$/d')
    echo "$accounts"
}

# リージョン一覧取得
get_regions() {
    if [[ -n "${REGIONS:-}" ]]; then
        echo "$REGIONS" | tr ',' '\n' | grep -v '^$'
    else
        # 全リージョン取得
        aws ec2 describe-regions \
            --all-regions \
            --query 'Regions[].RegionName' \
            --output text | tr '\t' '\n' | grep -v '^$' | sort
    fi
}

# 管理アカウントID取得
get_management_account_id() {
    aws organizations describe-organization \
        --query 'Organization.MasterAccountId' \
        --output text 2>/dev/null || echo ""
}

# アカウント・リージョンの有効化状況チェック
check_region_opt_status() {
    local account_id="$1"
    local region="$2"

    local status
    local management_account_id
    management_account_id=$(get_management_account_id)

    if [[ "$account_id" == "$management_account_id" ]]; then
        # 管理アカウントの場合は--account-idパラメータを省略
        status=$(aws account get-region-opt-status \
            --region-name "$region" \
            --output text 2>/dev/null || echo "ERROR")
    else
        # 通常のアカウントの場合
        status=$(aws account get-region-opt-status \
            --account-id "$account_id" \
            --region-name "$region" \
            --output text 2>/dev/null || echo "ERROR")
    fi

    if [[ "$status" == "ERROR" ]]; then
        echo "CHECK_ERROR"
    else
        # リージョン名とタブ文字を削除して、ステータスのみを抽出
        echo "$status" | awk '{print $NF}'
    fi
}

# メイン処理
main() {
    local dry_run="${DRY_RUN:-false}"

    log "組織内アカウント・リージョン有効化状況確認を開始"

    # 前提条件チェック
    check_prerequisites

    # 組織アカウント一覧取得
    log "組織アカウント一覧を取得中..."
    local accounts
    accounts=$(get_organization_accounts)

    if [[ -z "$accounts" ]]; then
        error_log "組織アカウントの取得に失敗しました"
        exit 1
    fi

    local account_count=$(echo "$accounts" | sed '/^$/d' | wc -l)
    log "組織アカウント取得完了: $account_count アカウント"

    # リージョン一覧取得
    log "リージョン一覧を取得中..."
    local regions
    regions=$(get_regions)

    if [[ -z "$regions" ]]; then
        error_log "リージョン一覧の取得に失敗しました"
        exit 1
    fi

    local region_count=$(echo "$regions" | sed '/^$/d' | wc -l)
    log "リージョン一覧取得完了: $region_count リージョン"

    # ドライランの場合は設定を表示して終了
    if [[ "$dry_run" == "true" ]]; then
        log "=== ドライラン実行 ==="
        log "対象アカウント数: $account_count"
        log "対象リージョン数: $region_count"
        log "総チェック数: $((account_count * region_count))"
        log "出力ファイル: $OUTPUT_FILE"
        log ""
        log "=== 対象アカウント ==="
        while IFS= read -r account_line; do
            account_id=$(echo "$account_line" | cut -f1)
            account_name=$(echo "$account_line" | cut -f2-)
            log "  - $account_id ($account_name)"
        done <<< "$accounts"
        log ""
        log "=== 対象リージョン ==="
        while IFS=$'\n' read -r region; do
            log "  - $region"
        done <<< "$regions"
        log "=== ドライラン終了 ==="
        exit 0
    fi

    # CSV ヘッダー作成
    cat > "$OUTPUT_FILE" << EOF
AccountId,AccountName,Region,RegionStatus,CheckTime
EOF

    # 各アカウント・リージョンの組み合わせでチェック実行
    local total_checks=$((account_count * region_count))
    local completed_checks=0

    log "チェック開始: 総チェック数 $total_checks"

    while IFS= read -r account_line; do
        # タブで分割してアカウントIDと名前を取得
        account_id=$(echo "$account_line" | cut -f1)
        account_name=$(echo "$account_line" | cut -f2- | sed 's/,/_/g')

        while IFS=$'\n' read -r region; do
            log "チェック中: $account_id ($account_name) - $region"

            # リージョン有効化状況チェック
            local region_opt_status
            region_opt_status=$(check_region_opt_status "$account_id" "$region")

            echo "$account_id,$account_name,$region,$region_opt_status,$(date '+%Y-%m-%d %H:%M:%S')" \
                >> "$OUTPUT_FILE"

            completed_checks=$((completed_checks + 1))
            log "進捗: $completed_checks/$total_checks ($(( completed_checks * 100 / total_checks ))%)"

        done <<< "$regions"
    done <<< "$accounts"

    log "チェック完了: $OUTPUT_FILE"

    # 結果サマリー
    local total_accounts
    local enabled_regions
    local disabled_regions
    local error_regions

    total_accounts=$(tail -n +2 "$OUTPUT_FILE" | cut -d',' -f1 | sort -u | \
        sed '/^$/d' | wc -l)
    enabled_regions=$(tail -n +2 "$OUTPUT_FILE" | grep -c "ENABLED")
    disabled_regions=$(tail -n +2 "$OUTPUT_FILE" | grep -c "DISABLED")
    error_regions=$(tail -n +2 "$OUTPUT_FILE" | grep -c "CHECK_ERROR")

    log "=== 結果サマリー ==="
    log "対象アカウント数: $total_accounts"
    log "リージョン有効化済み: $enabled_regions"
    log "リージョン無効化済み: $disabled_regions"
    log "チェックエラー: $error_regions"
    log "総チェック数: $total_checks"
    log "=================="
}

# スクリプト実行
parse_args "$@"
main

GuardDutyの設定状況の取得(実行アカウント:委任管理アカウント)
下記のシェルスクリプトを実行することで、GuardDuty の有効化状況を CSV で出力

#!/bin/bash

# =============================================================================
# GuardDuty Config Aggregator レポート生成スクリプト (CSV入力版)
# =============================================================================
# 説明: リージョン有効化状況CSVを入力として、有効化されたリージョンのみで
#       Config AggregatorからGuardDuty状況を確認してCSVで出力する
# 実行環境: 管理アカウントまたは委任管理アカウントのCloudShell
# 必要権限: Organizations, Config の読み取り権限
# =============================================================================

set -euo pipefail

# 定数定義
readonly SCRIPT_NAME="$(basename "$0")"
readonly DEFAULT_INPUT_FILE="account_region_status.csv"
readonly OUTPUT_FILE="guardduty_config_aggregator_merged_$(date +%Y%m%d_%H%M%S).csv"
readonly TEMP_DIR="/tmp/guardduty_report_$$"

# ログ関数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
}

error_log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $*" >&2
}

# CSV出力処理の統一
write_csv_record() {
    local account_id="$1"
    local account_name="$2" 
    local region="$3"
    local region_status="$4"
    local config_status="${5:--}"
    local config_recorder_guardduty_status="${6:--}"
    local guardduty_detector_id="${7:--}"
    local guardduty_status="${8:--}"
    local guardduty_created_at="${9:--}"
    local finding_frequency="${10:--}"
    local s3_protection="${11:--}"
    local eks_protection="${12:--}"
    local malware_protection="${13:--}"
    local rds_protection="${14:--}"
    local runtime_monitoring="${15:--}"
    local lambda_protection="${16:--}"
    local check_time="${17:-$(date '+%Y-%m-%d %H:%M:%S')}"

    echo "$account_id,$account_name,$region,$region_status,$config_status,$config_recorder_guardduty_status,$guardduty_detector_id,$guardduty_status,$guardduty_created_at,$finding_frequency,$s3_protection,$eks_protection,$malware_protection,$rds_protection,$runtime_monitoring,$lambda_protection,$check_time" >> "$OUTPUT_FILE"
}

# JSON解析処理の統一
parse_configuration_json() {
    local config_item="$1"
    local field_path="$2"  # 例: ".configuration" または ".RecordingGroup.AllSupported"

    local config_json_raw
    config_json_raw=$(echo "$config_item" | jq "$field_path" 2>/dev/null)

    local config_type
    config_type=$(echo "$config_json_raw" | jq -r 'type' 2>/dev/null)

    case "$config_type" in
        "object")
            echo "$config_json_raw"
            ;;
        "string")
            local config_str
            config_str=$(echo "$config_item" | jq -r "$field_path" 2>/dev/null)
            if [[ -n "$config_str" ]] && [[ "$config_str" != "null" ]]; then
                echo "$config_str" | jq . 2>/dev/null || echo "null"
            else
                echo "null"
            fi
            ;;
        *)
            echo "null"
            ;;
    esac
}

# 機能状態抽出のヘルパー関数
extract_feature_status() {
    local config_json="$1"
    local feature_name="$2"

    echo "$config_json" | jq -r ".Features[]? | select(.Name==\"$feature_name\") | .Status // \"DISABLED\"" 2>/dev/null || echo "DISABLED"
}

# GuardDuty設定解析をより明確に
analyze_guardduty_configuration() {
    local config_json="$1"
    local detector_id="$2"
    local created_at="$3"

    # Enable状態の判定
    local enable_status
    enable_status=$(echo "$config_json" | jq -r '.Enable' 2>/dev/null)

    local guardduty_status
    case "$enable_status" in
        "false") guardduty_status="SUSPENDED" ;;
        "true") guardduty_status="ENABLED" ;;
        "null"|"") guardduty_status="ENABLED" ;;  # デフォルト
        *) guardduty_status="UNKNOWN" ;;  # フェールセーフ
    esac

    # 保護機能の解析
    local s3_protection eks_protection malware_protection rds_protection
    local runtime_monitoring lambda_protection finding_frequency

    s3_protection=$(extract_feature_status "$config_json" "S3_DATA_EVENTS")
    eks_protection=$(extract_feature_status "$config_json" "EKS_AUDIT_LOGS")
    malware_protection=$(extract_feature_status "$config_json" "EBS_MALWARE_PROTECTION")
    rds_protection=$(extract_feature_status "$config_json" "RDS_LOGIN_EVENTS")
    lambda_protection=$(extract_feature_status "$config_json" "LAMBDA_NETWORK_LOGS")
    finding_frequency=$(echo "$config_json" | jq -r '.FindingPublishingFrequency // "-"')

    # EKS_RUNTIME_MONITORING または RUNTIME_MONITORING のどちらかが ENABLED の場合、RuntimeMonitoring を ENABLED とする
    local eks_runtime_status runtime_monitoring_status
    eks_runtime_status=$(extract_feature_status "$config_json" "EKS_RUNTIME_MONITORING")
    runtime_monitoring_status=$(extract_feature_status "$config_json" "RUNTIME_MONITORING")

    if [[ "$eks_runtime_status" == "ENABLED" || "$runtime_monitoring_status" == "ENABLED" ]]; then
        runtime_monitoring="ENABLED"
    else
        runtime_monitoring="DISABLED"
    fi

    # 日付フォーマット変換
    if [[ "$created_at" != "" && "$created_at" != "null" ]]; then
        created_at=$(date -d "@$created_at" '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo "$created_at")
    else
        created_at="-"
    fi

    echo "$detector_id,$guardduty_status,$created_at,$finding_frequency,$s3_protection,$eks_protection,$malware_protection,$rds_protection,$runtime_monitoring,$lambda_protection"
}

# 統一されたエラーハンドリング
handle_aws_api_error() {
    local operation="$1"
    local error_message="$2"

    case "$operation" in
        "config_aggregator")
            error_log "Config Aggregatorからの情報取得に失敗: $error_message"
            return 1
            ;;
        "guardduty_config")
            log "GuardDuty設定の取得に失敗、ERRORレコードを出力"
            echo "ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR,ERROR"
            return 0
            ;;
        *)
            error_log "不明なエラー: $error_message"
            return 1
            ;;
    esac
}

# 使用法表示
usage() {
    cat << EOF
使用法: $SCRIPT_NAME [OPTIONS]

GuardDuty Config Aggregator レポート生成スクリプト (CSV入力版)

OPTIONS:
    -h, --help              このヘルプを表示
    -i, --input FILE        入力CSVファイルを指定 (デフォルト: $DEFAULT_INPUT_FILE)
    -a, --aggregator NAME   使用するConfig Aggregator名を指定
    -o, --output FILE       出力ファイル名を指定 (デフォルト: $OUTPUT_FILE)
    --list-aggregators     利用可能なConfig Aggregatorを表示
    --dry-run              実際のチェックを行わずに設定を表示

例:
    $SCRIPT_NAME --list-aggregators
    $SCRIPT_NAME -i my_input.csv -a my-config-aggregator
    $SCRIPT_NAME -i my_input.csv -a my-config-aggregator -o my_output.csv
    $SCRIPT_NAME -i my_input.csv -a my-config-aggregator --dry-run

注意:
    Config Aggregatorの指定は必須です。
    利用可能なAggregatorを確認するには --list-aggregators を使用してください。

    入力CSVファイルのフォーマット:
    AccountId,AccountName,Region,RegionStatus,CheckTime

    RegionStatus が ENABLED, ENABLING, ENABLED_BY_DEFAULT の場合のみ
    Config および GuardDuty の有効状況をチェックします。
EOF
}

# 引数解析
parse_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                usage
                exit 0
                ;;
            -i|--input)
                INPUT_FILE="$2"
                shift 2
                ;;
            -a|--aggregator)
                AGGREGATOR_NAME="$2"
                shift 2
                ;;
            -o|--output)
                OUTPUT_FILE="$2"
                shift 2
                ;;
            --list-aggregators)
                LIST_AGGREGATORS=true
                shift
                ;;
            --dry-run)
                DRY_RUN=true
                shift
                ;;
            *)
                error_log "不明なオプション: $1"
                usage
                exit 1
                ;;
        esac
    done

    # 入力ファイルのデフォルト設定
    if [[ -z "${INPUT_FILE:-}" ]]; then
        INPUT_FILE="$DEFAULT_INPUT_FILE"
    fi

    # アグリゲーターの指定が必須(--list-aggregators以外の場合)
    if [[ "${LIST_AGGREGATORS:-false}" == "false" ]] && [[ -z "${AGGREGATOR_NAME:-}" ]]; then
        error_log "Config Aggregatorの指定が必要です"
        error_log ""
        error_log "使用方法: $SCRIPT_NAME -i input.csv -a <AGGREGATOR_NAME>"
        error_log "例: $SCRIPT_NAME -i $DEFAULT_INPUT_FILE -a my-config-aggregator"
        error_log ""
        error_log "利用可能なAggregatorを確認するには: $SCRIPT_NAME --list-aggregators"
        exit 1
    fi
}

# 前提条件チェック
check_prerequisites() {
    log "前提条件をチェック中..."

    # AWS CLIの確認
    if ! command -v aws &> /dev/null; then
        error_log "AWS CLI がインストールされていません"
        exit 1
    fi

    # jqの確認
    if ! command -v jq &> /dev/null; then
        error_log "jq がインストールされていません"
        exit 1
    fi

    # AWS認証情報の確認
    if ! aws sts get-caller-identity &> /dev/null; then
        error_log "AWS認証情報が設定されていません"
        exit 1
    fi

    # 組織アカウントかどうかの確認
    if ! aws organizations describe-organization &> /dev/null; then
        error_log "組織の管理アカウントまたは委任管理アカウントで実行してください"
        exit 1
    fi

    # 入力ファイルの存在確認
    if [[ "${LIST_AGGREGATORS:-false}" == "false" ]] && [[ ! -f "$INPUT_FILE" ]]; then
        error_log "入力ファイルが見つかりません: $INPUT_FILE"
        exit 1
    fi

    # 一時ディレクトリ作成
    mkdir -p "$TEMP_DIR"

    log "前提条件チェック完了"
}

# 利用可能なConfig Aggregatorを表示
list_config_aggregators() {
    local aggregators_detail
    aggregators_detail=$(aws configservice describe-configuration-aggregators \
        --query 'ConfigurationAggregators[].[ConfigurationAggregatorName,OrganizationAggregationSource.AllAwsRegions]' \
        --output table 2>/dev/null || echo "")

    if [[ -z "$aggregators_detail" ]]; then
        error_log "Config Aggregatorが見つかりません"
        return 1
    fi

    echo "=== 利用可能なConfig Aggregator ==="
    echo "$aggregators_detail"
    echo "=================================="
    echo ""
    echo "使用方法: $SCRIPT_NAME -i input.csv -a <AGGREGATOR_NAME>"
    echo "例: $SCRIPT_NAME -i $DEFAULT_INPUT_FILE -a my-config-aggregator"
}

# 入力CSVファイルの読み込みと検証
load_input_data() {
    # ヘッダー行の確認
    local header
    header=$(head -n 1 "$INPUT_FILE")
    if [[ "$header" != "AccountId,AccountName,Region,RegionStatus,CheckTime" ]]; then
        error_log "入力CSVファイルのヘッダーが不正です"
        error_log "期待値: AccountId,AccountName,Region,RegionStatus,CheckTime"
        error_log "実際値: $header"
        exit 1
    fi

    # データ行数の確認
    local data_lines
    data_lines=$(tail -n +2 "$INPUT_FILE" | wc -l)
    if [[ $data_lines -eq 0 ]]; then
        error_log "入力CSVファイルにデータがありません"
        exit 1
    fi
}

# 有効化されているリージョンのみを抽出
get_enabled_regions_data() {
    # ENABLED, ENABLING, ENABLED_BY_DEFAULT の行のみを抽出
    local enabled_data
    enabled_data=$(tail -n +2 "$INPUT_FILE" | \
        grep -E "(ENABLED|ENABLING|ENABLED_BY_DEFAULT)" || echo "")

    if [[ -z "$enabled_data" ]]; then
        error_log "有効化されているリージョンが見つかりません"
        exit 1
    fi

    echo "$enabled_data"
}

# [削除] 使用されなくなった関数を削除してコードを整理しました

# 統一版: 全アカウント・リージョンのConfig情報を一括取得
get_all_config_data_unified() {
    local aggregator_name="$1"

    # 全ConfigurationRecorderの情報を取得(ResourceIdと設定詳細も含めて)
    local config_recorders
    if ! config_recorders=$(aws configservice list-aggregate-discovered-resources \
        --configuration-aggregator-name "$aggregator_name" \
        --resource-type "AWS::Config::ConfigurationRecorder" \
        --query 'ResourceIdentifiers[].[SourceAccountId,SourceRegion,ResourceId]' \
        --output text 2>/dev/null); then
        config_recorders=""
    fi

    # 全GuardDuty Detectorの情報を取得(ResourceIdも含めて)
    local guardduty_resources
    if ! guardduty_resources=$(aws configservice list-aggregate-discovered-resources \
        --configuration-aggregator-name "$aggregator_name" \
        --resource-type "AWS::GuardDuty::Detector" \
        --query 'ResourceIdentifiers[].[SourceAccountId,SourceRegion,ResourceId]' \
        --output text 2>/dev/null); then
        guardduty_resources=""
    fi

    # 結果を連想配列に保存
    # 既存の連想配列をクリア
    unset guardduty_status_map 2>/dev/null || true
    unset guardduty_resource_map 2>/dev/null || true
    unset config_recorder_map 2>/dev/null || true
    unset config_recorder_guardduty_map 2>/dev/null || true

    # 新しい連想配列を宣言
    declare -gA guardduty_status_map
    declare -gA guardduty_resource_map
    declare -gA config_recorder_map
    declare -gA config_recorder_guardduty_map

    # GuardDuty Detectorの情報を処理
    local guardduty_count=0
    if [[ -n "$guardduty_resources" ]]; then
        while IFS=$'\t' read -r account_id region resource_id; do
            if [[ -n "$account_id" && -n "$region" && -n "$resource_id" ]]; then
                local key="${account_id}:${region}"
                guardduty_status_map["$key"]="true"
                guardduty_resource_map["$key"]="$resource_id"
                guardduty_count=$((guardduty_count + 1))
            fi
        done <<< "$guardduty_resources"
    fi

    # ConfigurationRecorderの情報を処理
    local config_recorder_count=0
    if [[ -n "$config_recorders" ]]; then
        while IFS=$'\t' read -r account_id region resource_id; do
            if [[ -n "$account_id" && -n "$region" && -n "$resource_id" ]]; then
                local key="${account_id}:${region}"
                config_recorder_map["$key"]="$resource_id"

                # ConfigurationRecorderの詳細設定を取得してGuardDuty記録対象かを判定
                local guardduty_recording_status
                guardduty_recording_status=$(get_config_recorder_guardduty_setting_details "$aggregator_name" "$account_id" "$region" "$resource_id")
                config_recorder_guardduty_map["$key"]="$guardduty_recording_status"

                config_recorder_count=$((config_recorder_count + 1))
            fi
        done <<< "$config_recorders"
    fi
}

# ConfigurationRecorderの詳細設定を取得してGuardDuty記録対象かを判定(リファクタリング版)
get_config_recorder_guardduty_setting_details() {
    local aggregator_name="$1"
    local account_id="$2"
    local region="$3"
    local recorder_name="$4"

    # ConfigurationRecorderの詳細設定を取得
    local config_response
    config_response=$(aws configservice get-aggregate-resource-config \
        --configuration-aggregator-name "$aggregator_name" \
        --resource-identifier ResourceType="AWS::Config::ConfigurationRecorder",ResourceId="$recorder_name",SourceAccountId="$account_id",SourceRegion="$region" \
        2>/dev/null || echo "")

    if [[ -z "$config_response" ]]; then
        echo "UNKNOWN"
        return
    fi

    # RecordingGroupの設定を解析
    local config_item
    config_item=$(echo "$config_response" | jq -r '.ConfigurationItem')

    # JSON設定解析の共通処理を使用
    local configuration
    configuration=$(parse_configuration_json "$config_item" ".configuration")

    if [[ "$configuration" == "null" ]]; then
        echo "UNKNOWN"
        return
    fi

    # AllSupportedの確認
    local all_supported
    all_supported=$(echo "$configuration" | jq -r '.RecordingGroup.AllSupported // false')

    if [[ "$all_supported" == "true" ]]; then
        echo "ENABLED"
        return
    fi

    # ResourceTypesでGuardDutyが含まれているかを確認
    local has_guardduty
    has_guardduty=$(echo "$configuration" | jq -r '.RecordingGroup.ResourceTypes[]? // empty' | grep -c "AWS::GuardDuty::Detector" 2>/dev/null || echo "0")
    # 改行を除去
    has_guardduty=$(echo "$has_guardduty" | tr -d '\n')

    if [[ "$has_guardduty" -gt 0 ]]; then
        echo "ENABLED"
    else
        echo "DISABLED"
    fi
}

# 連想配列からConfigurationRecorderのGuardDuty記録設定を取得
check_config_recorder_guardduty_setting() {
    local account_id="$1" 
    local region="$2"
    local key="${account_id}:${region}"

    # 連想配列から事前に取得済みの情報を返す
    echo "${config_recorder_guardduty_map[$key]:-DISABLED}"
}

# 統一版: 保存済みデータからGuardDuty ResourceIdを取得
get_guardduty_resource_id() {
    local account_id="$1"
    local region="$2"
    local key="${account_id}:${region}"

    echo "${guardduty_resource_map[$key]:-}"
}

# 統一版: 保存済みデータからConfig状況を確認(ConfigurationRecorderの存在で判定)
get_config_status_unified() {
    local account_id="$1"
    local region="$2"
    local key="${account_id}:${region}"

    # ConfigurationRecorderが存在する場合、Configが有効と判定
    if [[ -n "${config_recorder_map[$key]:-}" ]]; then
        echo "ENABLED"
    else
        echo "DISABLED"
    fi
}

# 統一版: 保存済みデータからGuardDuty Detector状況を確認
get_guardduty_detector_status_unified() {
    local account_id="$1"
    local region="$2"
    local key="${account_id}:${region}"

    if [[ "${guardduty_status_map[$key]:-}" == "true" ]]; then
        echo "true"
    else
        echo "false"
    fi
}

# GuardDuty設定詳細情報を取得(リファクタリング版)
get_guardduty_config_details_refactored() {
    local aggregator_name="$1"
    local account_id="$2"
    local region="$3"
    local detector_id="$4"

    # Config Aggregatorから詳細設定を取得
    local config_response
    config_response=$(aws configservice get-aggregate-resource-config \
        --configuration-aggregator-name "$aggregator_name" \
        --resource-identifier ResourceType="AWS::GuardDuty::Detector",ResourceId="$detector_id",SourceAccountId="$account_id",SourceRegion="$region" \
        2>/dev/null || echo "")

    if [[ -z "$config_response" ]]; then
        handle_aws_api_error "guardduty_config" "Config Aggregatorから情報を取得できませんでした"
        return
    fi

    # 設定情報を解析
    local config_item
    config_item=$(echo "$config_response" | jq -r '.ConfigurationItem')

    # JSON設定解析の共通処理を使用
    local config_json
    config_json=$(parse_configuration_json "$config_item" ".configuration")

    if [[ "$config_json" == "null" ]]; then
        handle_aws_api_error "guardduty_config" "configuration情報の解析に失敗"
        return
    fi

    # configurationItemStatusを使用してリソースの状態を判定
    local config_item_status
    config_item_status=$(echo "$config_item" | jq -r '.configurationItemStatus // ""')

    # リソース状態に応じて処理を分岐
    case "$config_item_status" in
        "OK"|"ResourceDiscovered")
            local created_at
            created_at=$(echo "$config_item" | jq -r '.resourceCreationTime // ""' | tr -d '"')
            analyze_guardduty_configuration "$config_json" "$detector_id" "$created_at"
            ;;
        "ResourceDeleted")
            echo "$detector_id,DELETED,-,-,-,-,-,-,-,-"
            ;;
        "ResourceNotRecorded"|"ResourceDeletedNotRecorded")
            echo "$detector_id,UNKNOWN,-,-,-,-,-,-,-,-"
            ;;
        *)
            echo "$detector_id,UNKNOWN,-,-,-,-,-,-,-,-"
            ;;
    esac
}

# Config Aggregator検証を独立した関数に
validate_config_aggregator() {
    local aggregator_name="$1"

    if ! aws configservice describe-configuration-aggregators \
        --configuration-aggregator-names "$aggregator_name" \
        --query 'ConfigurationAggregators[0].ConfigurationAggregatorName' \
        --output text &> /dev/null; then
        error_log "指定されたConfig Aggregator '$aggregator_name' が見つかりません"
        error_log "利用可能なAggregatorを確認するには: $SCRIPT_NAME --list-aggregators"
        return 1
    fi
    return 0
}

# CSV ヘッダー作成
create_csv_header() {
    cat > "$OUTPUT_FILE" << EOF
AccountId,AccountName,Region,RegionStatus,ConfigStatus,ConfigRecorderGuardDutyStatus,GuardDutyDetectorId,GuardDutyStatus,GuardDutyCreatedAt,FindingPublishingFrequency,S3Protection,EKSProtection,MalwareProtectionForEC2,RDSProtection,RuntimeMonitoring,LambdaProtection,CheckTime
EOF
}

# 各行処理を独立した関数に
process_account_region() {
    local account_id="$1"
    local account_name="$2"
    local region="$3"
    local region_status="$4"
    local check_time="$5"
    local aggregator_name="$6"

    if [[ "$region_status" =~ ^(ENABLED|ENABLING|ENABLED_BY_DEFAULT)$ ]]; then
        process_enabled_region "$account_id" "$account_name" "$region" "$region_status" "$aggregator_name"
    else
        write_csv_record "$account_id" "$account_name" "$region" "$region_status" "-" "-" "-" "-" "-" "-" "-" "-" "-" "-" "-" "-" "-" "$check_time"
    fi
}

# 有効化リージョンの処理
process_enabled_region() {
    local account_id="$1"
    local account_name="$2"
    local region="$3"
    local region_status="$4"
    local aggregator_name="$5"

    # 正しい判定順序での評価:
    # 1. Config が有効化されているかチェック
    local config_status_simple
    config_status_simple=$(get_config_status_unified "$account_id" "$region")

    # 2. GuardDuty のリソース記録が有効であるかチェック
    local config_recorder_guardduty_status
    if [[ "$config_status_simple" == "ENABLED" ]]; then
        config_recorder_guardduty_status=$(check_config_recorder_guardduty_setting "$account_id" "$region")
    else
        config_recorder_guardduty_status="DISABLED"
    fi

    # 3. GuardDuty が有効かチェック
    local guardduty_detector_recorded
    guardduty_detector_recorded=$(get_guardduty_detector_status_unified "$account_id" "$region")

    # ConfigRecorderでGuardDutyが記録対象外の場合は、詳細情報を取得しない
    if [[ "$config_recorder_guardduty_status" == "DISABLED" ]]; then
        write_csv_record "$account_id" "$account_name" "$region" "$region_status" "$config_status_simple" "$config_recorder_guardduty_status"
    elif [[ "$guardduty_detector_recorded" == "true" ]]; then
        process_guardduty_detected "$account_id" "$account_name" "$region" "$region_status" "$config_status_simple" "$config_recorder_guardduty_status" "$aggregator_name"
    else
        write_csv_record "$account_id" "$account_name" "$region" "$region_status" "$config_status_simple" "$config_recorder_guardduty_status" "DISABLED"
    fi
}

# GuardDuty検出時の処理
process_guardduty_detected() {
    local account_id="$1"
    local account_name="$2"
    local region="$3"
    local region_status="$4"
    local config_status_simple="$5"
    local config_recorder_guardduty_status="$6"
    local aggregator_name="$7"

    local resource_id
    resource_id=$(get_guardduty_resource_id "$account_id" "$region")

    if [[ -n "$resource_id" ]]; then
        local guardduty_details
        guardduty_details=$(get_guardduty_config_details_refactored "$aggregator_name" "$account_id" "$region" "$resource_id")

        # guardduty_detailsは既にカンマ区切り形式なので、元の書き方を保持
        echo "$account_id,$account_name,$region,$region_status,$config_status_simple,$config_recorder_guardduty_status,$guardduty_details,$(date '+%Y-%m-%d %H:%M:%S')" >> "$OUTPUT_FILE"
    else
        write_csv_record "$account_id" "$account_name" "$region" "$region_status" "$config_status_simple" "$config_recorder_guardduty_status" "-" "ENABLED"
    fi
}

# データ処理のメイン関数
process_input_csv() {
    local aggregator_name="$1"

    local total_lines
    total_lines=$(tail -n +2 "$INPUT_FILE" | wc -l)
    local processed_lines=0

    # 入力CSVの各行を処理
    while IFS=',' read -r account_id account_name region region_opt_status check_time; do
        processed_lines=$((processed_lines + 1))

        # 空行をスキップ
        if [[ -z "$account_id" ]]; then
            continue
        fi

        process_account_region "$account_id" "$account_name" "$region" "$region_opt_status" "$check_time" "$aggregator_name"

    done < <(tail -n +2 "$INPUT_FILE")
}

# レポートサマリー表示
show_report_summary() {
    local total_accounts enabled_checked disabled_skipped config_configured
    local guardduty_found guardduty_enabled s3_protection_enabled malware_protection_enabled

    total_accounts=$(tail -n +2 "$OUTPUT_FILE" | cut -d',' -f1 | sort -u | wc -l)
    enabled_checked=$(tail -n +2 "$OUTPUT_FILE" | grep -c -E "(ENABLED|ENABLING|ENABLED_BY_DEFAULT)")
    disabled_skipped=$(tail -n +2 "$OUTPUT_FILE" | grep -c -E "(DISABLED|DISABLING)")
    config_configured=$(tail -n +2 "$OUTPUT_FILE" | grep -c "ENABLE")
    guardduty_found=$(tail -n +2 "$OUTPUT_FILE" | cut -d',' -f6 | grep -c -v -E "(DISABLED|-)")
    guardduty_enabled=$(tail -n +2 "$OUTPUT_FILE" | cut -d',' -f7 | grep -c "ENABLED")
    s3_protection_enabled=$(tail -n +2 "$OUTPUT_FILE" | cut -d',' -f11 | grep -c "ENABLED")
    malware_protection_enabled=$(tail -n +2 "$OUTPUT_FILE" | cut -d',' -f13 | grep -c "ENABLED")

    log "=== 結果サマリー ==="
    log "対象アカウント数: $total_accounts"
    log "有効化リージョン(チェック済み): $enabled_checked"
    log "無効化リージョン(スキップ): $disabled_skipped"
    log "Config設定済み: $config_configured"
    log "GuardDuty Detector検出: $guardduty_found"
    log "GuardDuty Detector有効化済み: $guardduty_enabled"
    log "S3 Protection有効化済み: $s3_protection_enabled"
    log "Malware Protection有効化済み: $malware_protection_enabled"
    log "=================="
}

# レポート生成処理を独立した関数に
generate_guardduty_report() {
    local aggregator_name="$1"

    # CSV ヘッダー作成
    create_csv_header

    # データ処理
    process_input_csv "$aggregator_name"

    log "処理完了: $OUTPUT_FILE"

    # サマリー表示
    show_report_summary
}

# メイン処理
main() {
    local dry_run="${DRY_RUN:-false}"
    local list_aggregators="${LIST_AGGREGATORS:-false}"

    log "GuardDuty Config Aggregator レポート生成を開始 (CSV入力版)"

    # 前提条件チェック
    check_prerequisites

    # Aggregatorリスト表示の場合
    if [[ "$list_aggregators" == "true" ]]; then
        list_config_aggregators
        exit 0
    fi

    # Config Aggregatorの確認
    if ! validate_config_aggregator "$AGGREGATOR_NAME"; then
        exit 1
    fi

    local aggregator_name="$AGGREGATOR_NAME"

    # 入力CSVファイルの読み込み
    load_input_data

    # 有効化されているリージョンのデータを取得
    local enabled_regions_data
    enabled_regions_data=$(get_enabled_regions_data)

    # Config AggregatorからConfigおよびGuardDutyリソースを取得
    get_all_config_data_unified "$aggregator_name"

    # 有効化されているリージョンの統計
    local enabled_count
    enabled_count=$(echo "$enabled_regions_data" | wc -l)

    # 無効化されているリージョンの統計
    local disabled_count
    disabled_count=$(tail -n +2 "$INPUT_FILE" | \
        grep -c -E "(DISABLED|DISABLING)" || echo "0")

    # ドライランの場合は設定を表示して終了
    if [[ "$dry_run" == "true" ]]; then
        log "=== ドライラン実行 ==="
        log "入力ファイル: $INPUT_FILE"
        log "Config Aggregator: $aggregator_name"
        log "有効化リージョン数: $enabled_count"
        log "無効化リージョン数: $disabled_count"
        log "出力ファイル: $OUTPUT_FILE"
        log "=== ドライラン終了 ==="
        exit 0
    fi

    # レポート生成処理
    generate_guardduty_report "$aggregator_name"

    # 一時ディレクトリクリーンアップ
    rm -rf "$TEMP_DIR"
}

# スクリプト実行
parse_args "$@"
main

出力結果

下記はCSV出力をスプレッドシートにインポートした結果です。
数が多いため、リージョンを絞っています。

ただし、Config の設定状況により全ての情報が取得できるわけではありません。
特に下記のアカウント・リージョンについては、別途確認を行うことをおすすめします。

  • ConfigStatus が DISABLED:Config が有効化されていないため、GuardDuty の情報が未取得
  • ConfigRecorderGuardDutyStatus が DISABLED:Config にて GuardDuty を記録していないため、GuardDuty の情報が未取得

CleanShot20250728at19.12.17

後片付け

1. AWS Config Aggregator の削除(実行アカウント:委任管理アカウント)

1-1. AWS Config Aggregator の削除

aws configservice delete-configuration-aggregator \
	--configuration-aggregator-name OrgConfigAggregator

1-2. AWS Config Aggregator の削除確認

aws configservice describe-configuration-aggregators \
	--configuration-aggregator-names OrgConfigAggregator

2. AWS Config Aggregator 用 IAMロール の削除(実行アカウント:委任管理アカウント)

2-1. IAMロール 削除

aws iam delete-role --role-name OrgConfigAggregatorRole

2-2. IAMロール の削除確認

aws iam get-role --role-name OrgConfigAggregatorRole

3. AWS Config の委任管理アカウントの解除(実行アカウント:管理アカウント)

3-1. AWS Config の委任管理アカウントの解除

aws organizations deregister-delegated-administrator \
	--service-principal=config.amazonaws.com \
	--account-id "${DelegatedAdministratorAccountID}"

aws organizations deregister-delegated-administrator \
	--service-principal=config-multiaccountsetup.amazonaws.com \
	--account-id "${DelegatedAdministratorAccountID}"

3-2. AWS Config の委任管理アカウントの解除確認

aws organizations list-delegated-administrators --output table \
	--service-principal=config.amazonaws.com

aws organizations list-delegated-administrators --output table \
	--service-principal=config-multiaccountsetup.amazonaws.com

3-3. AWS Config の信頼されたアクセスの無効化

# config-multiaccountsetup.amazonaws.com の無効化
aws organizations disable-aws-service-access \
	--service-principal=config-multiaccountsetup.amazonaws.com

# config.amazonaws.com の無効化
aws organizations disable-aws-service-access \
	--service-principal=config.amazonaws.com

3-4. AWS Config の信頼されたアクセスの確認

aws organizations list-aws-service-access-for-organization --output table

4. AWS Account Management の信頼されたアクセスの無効化(実行アカウント:管理アカウント)

4-1. AWS Account Management の信頼されたアクセスの無効化

aws organizations disable-aws-service-access \
	--service-principal account.amazonaws.com

4-2. AWS Account Management の信頼されたアクセスの確認

aws organizations list-aws-service-access-for-organization --output table

あとがき

今回、Aggregator を活用した GuardDuty 設定状況の一括調査方法を検証しました。

今回作成したスクリプトで、従来の確認作業を大幅に効率化できたかと思います。
またCSV形式での出力により、Excel等での詳細分析や可視化も容易にできました。

以上、くろすけでした!

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.