(小ネタ)CloudTrail が全リージョンで有効か無効か確認するスクリプトを CloudShell で実行する
コーヒーが好きな emi です。
スタンドアロンの AWS アカウントを Control Tower に参加させる前に Config の有効化状況を確認するスクリプトを以下のブログで作成し実行しました。
次は、CloudTrail 証跡が全リージョンで有効化どうか確認するスクリプトを作成して CloudShell で実行してみます。
CloudTrail 証跡で料金が発生するケース
CloudTrail 証跡は 1 つ目は無料ですが、2 つ目以降は有料になります。
よくあるミスとして、Control Tower を有効化した際、既存で設定されていた CloudTrail 証跡に追加で Coltrol Tower の組織レベルの CloudTrail 証跡が有効化されてしまい、課金が発生するケースがあります。
Config とは違い、CloudTrail 証跡があっても Control Tower への登録は成功します。CloudTrail でのデータイベントの取得など、別の用途で取得する場合もあるためです。
しかし、特に用途がないのに二重に証跡を取得してコスト増になっては無駄なので、生成 AI の力も借り、CloudTrail 証跡が有効になっているかどうか確認するスクリプトを作成し CloudShell で実行してみました。
過去何回も擦られたネタかもしれませんが、読むのと自分でやるのとでは理解に差があると思うので改めて記事に残しておきます。
作成したスクリプト
#!/bin/bash
# Get all available AWS regions
regionAry=($(aws ec2 describe-regions --all-regions --query "Regions[].RegionName" --output text))
# Print header
printf "| %-18s | %-30s | %-14s | %-12s |\n" "Region" "Trail Name" "Multi-Region?" "Org Trail?"
printf "|--------------------|--------------------------------|----------------|--------------|\n"
for region in "${regionAry[@]}"; do
    # Get trail list with name and isMultiRegion info
    trails=$(aws cloudtrail describe-trails \
        --region "$region" \
        --query "trailList[*].[Name,IsMultiRegionTrail]" \
        --output text 2>/dev/null)
    if [ -z "$trails" ]; then
        # No trail found in this region
        printf "| %-18s | %-30s | %-14s | %-12s |\n" "$region" "-" "-" "-"
    else
        # Process each trail
        while IFS=$'\t' read -r trailName isMulti; do
            if [ "$trailName" != "None" ] && [ -n "$trailName" ]; then
                # Check if this trail is an organization trail
                isOrg=$(aws cloudtrail get-trail \
                    --name "$trailName" \
                    --region "$region" \
                    --query "Trail.IsOrganizationTrail" \
                    --output text 2>/dev/null)
            else
                isOrg="-"
            fi
            printf "| %-18s | %-30s | %-14s | %-12s |\n" "$region" "$trailName" "$isMulti" "$isOrg"
        done <<< "$trails"
    fi
done
スクリプトの説明
このスクリプトは、各リージョンにおける CloudTrail の証跡が存在するかどうかを確認し、表形式で一覧表示するものです。CloudTrail には以下 3 種類の証跡が存在し、それぞれ有効か無効か判定します。
- 単一リージョンの証跡
- マルチリージョンの証跡
- 組織レベルの証跡
1. 全リージョンを取得して配列に格納
regionAry=($(aws ec2 describe-regions --all-regions --query "Regions[].RegionName" --output text))
- aws ec2 describe-regionsで全リージョンのリージョン名を取得
- regionAryはリージョン名の配列
- --all-regionsを指定すると全リージョンを取得できる
2. 表のヘッダーを表示
printf "| %-18s | %-30s | %-14s | %-12s |\n" "Region" "Trail Name" "Multi-Region?" "Org Trail?"
printf "|--------------------|--------------------------------|----------------|--------------|\n"
- 出力結果をテーブル形式にするために、ヘッダー(見出し)と罫線を表示
- --output tableだとリージョンの数だけテーブルが出力されるようになってしまったためこのように人力で成形
 
- Region:リージョン名
- Trail Name:CloudTrail の証跡名
- Multi-Region?:マルチリージョン証跡かどうか(- true/- false)
- Org Trail?:組織トレイルであるか(true/false)
3. 各リージョンで CloudTrail を確認
for region in "${regionAry[@]}"; do
- 配列 regionAryに入っているすべてのリージョンに対してループ処理
4. describe-trails 実行
trails=$(aws cloudtrail describe-trails \
    --region "$region" \
    --query "trailList[*].[Name,IsMultiRegionTrail]" \
    --output text 2>/dev/null)
- 各リージョンで CloudTrail の情報を取得
- --queryで- trailListの中から- Nameと- IsMultiRegionTrailだけを取り出し
- --output textでタブ区切りのテキスト形式に変換
- 2>/dev/nullでエラー出力を無視
5. CloudTrail 証跡が存在しない場合の出力
if [ -z "$trails" ]; then
    printf "| %-18s | %-30s | %-14s | %-12s |\n" "$region" "-" "-" "-"
- resultが空(=トレイルが存在しない)場合は「-」で表示
6. CloudTrail 証跡がある場合の出力
while IFS=$'\t' read -r trailName isMulti; do
- 複数トレイルがある場合、1 つずつ処理
- --output textを使うと出力が タブ区切り(- \t)になるため- IFS=$'\t'を設定- IFS(Internal Field Separator(内部フィールド区切り文字):Bash が「文字列をどこで区切って単語に分けるかを決めるための変数
 
- trailNameと- isMultiに分割して変数へ代入
7. 各 CloudTrail 証跡について組織レベルか確認
if [ "$trailName" != "None" ] && [ -n "$trailName" ]; then
    isOrg=$(aws cloudtrail get-trail \
        --name "$trailName" \
        --region "$region" \
        --query "Trail.IsOrganizationTrail" \
        --output text 2>/dev/null)
else
    isOrg="-"
fi
- get-trailコマンドを使ってその証証跡組織レベルかどうか判定
- Trail.IsOrganizationTrailで- true/- falseを取得
- 証跡名が "None"や空なら"-"を表示
8. 結果をテーブルに出力
printf "| %-18s | %-30s | %-14s | %-12s |\n" "$region" "$trailName" "$isMulti" "$isOrg"
- 4 列の表形式で整形して表示
CloudShell で実行
CloudShell で check-trail-status.sh を保存します。
- vim check-trail-status.shと入力し vim エディタを開く
- :set paste + Enterで貼り付けモードにする
- iを押下し編集モードにする
- スクリプトの中身を貼り付ける
- escを押下し編集モードを抜ける
- :wq + Enterで保存し閉じる
- 保存できたか cat check-trail-status.shで確認する
- chmod +x check-trail-status.shで実行権限を付与
では、CloudShell でスクリプトを実行します。
./check-trail-status.sh
▼実行結果
~ $ ./check-trail-status.sh 
| Region             | Trail Name                     | Multi-Region?  | Org Trail?   |
|--------------------|--------------------------------|----------------|--------------|
| ap-south-2         | -                              | -              | -            |
| ap-south-1         | -                              | -              | -            |
| eu-south-1         | -                              | -              | -            |
| eu-south-2         | -                              | -              | -            |
| me-central-1       | -                              | -              | -            |
| il-central-1       | -                              | -              | -            |
| ca-central-1       | -                              | -              | -            |
| mx-central-1       | -                              | -              | -            |
| eu-central-1       | -                              | -              | -            |
| eu-central-2       | -                              | -              | -            |
| us-west-1          | -                              | -              | -            |
| us-west-2          | -                              | -              | -            |
| af-south-1         | -                              | -              | -            |
| eu-north-1         | -                              | -              | -            |
| eu-west-3          | -                              | -              | -            |
| eu-west-2          | -                              | -              | -            |
| eu-west-1          | -                              | -              | -            |
| ap-northeast-3     | -                              | -              | -            |
| ap-northeast-2     | -                              | -              | -            |
| me-south-1         | -                              | -              | -            |
| ap-northeast-1     | -                              | -              | -            |
| sa-east-1          | -                              | -              | -            |
| ap-east-1          | -                              | -              | -            |
| ca-west-1          | -                              | -              | -            |
| ap-southeast-1     | -                              | -              | -            |
| ap-southeast-2     | -                              | -              | -            |
| ap-southeast-3     | -                              | -              | -            |
| ap-southeast-4     | -                              | -              | -            |
| us-east-1          | -                              | -              | -            |
| ap-southeast-5     | -                              | -              | -            |
| us-east-2          | -                              | -              | -            |
| ap-southeast-7     | -                              | -              | -            |
~ $ 
いいですね。CloudTrail 証跡が無いことが分かりました。
さて、ちゃんとスクリプトが発動するか確認するため、バージニア北部リージョン(us-east-1)で組織レベルの証跡有効化をおこない、再度スクリプトを CloudShell で実行してみます。
~ $ ./check-trail-status.sh 
| Region             | Trail Name                     | Multi-Region?  | Org Trail?   |
|--------------------|--------------------------------|----------------|--------------|
| ap-south-2         | -                              | -              | -            |
| ap-south-1         | management-events              | True           |              |
| eu-south-1         | -                              | -              | -            |
| eu-south-2         | -                              | -              | -            |
| me-central-1       | -                              | -              | -            |
| il-central-1       | -                              | -              | -            |
| ca-central-1       | management-events              | True           |              |
| mx-central-1       | -                              | -              | -            |
| eu-central-1       | management-events              | True           |              |
| eu-central-2       | -                              | -              | -            |
| us-west-1          | management-events              | True           |              |
| us-west-2          | management-events              | True           |              |
| af-south-1         | -                              | -              | -            |
| eu-north-1         | management-events              | True           |              |
| eu-west-3          | management-events              | True           |              |
| eu-west-2          | management-events              | True           |              |
| eu-west-1          | management-events              | True           |              |
| ap-northeast-3     | management-events              | True           |              |
| ap-northeast-2     | management-events              | True           |              |
| me-south-1         | -                              | -              | -            |
| ap-northeast-1     | management-events              | True           |              |
| sa-east-1          | management-events              | True           |              |
| ap-east-1          | -                              | -              | -            |
| ca-west-1          | -                              | -              | -            |
| ap-southeast-1     | management-events              | True           |              |
| ap-southeast-2     | management-events              | True           |              |
| ap-southeast-3     | -                              | -              | -            |
| ap-southeast-4     | -                              | -              | -            |
| us-east-1          | management-events              | True           | True         |
| ap-southeast-5     | -                              | -              | -            |
| us-east-2          | management-events              | True           |              |
| ap-southeast-7     | -                              | -              | -            |
~ $ 
いいですね!バージニア北部リージョン(us-east-1)で組織レベルの証跡が有効になっていて、オプトインリージョンに証跡が存在することが確認できました。
この場合、バージニア北部リージョン(us-east-1)で組織レベルの証跡を削除すれば、全リージョンで証跡が無効になります。
おわりに
本記事への質問やご要望については画面下部のお問い合わせ「DevelopersIO について」からご連絡ください。記事に関してお問い合わせいただけます。
参考











