AWS Trusted Advisor の全件チェック結果をスクリプトでエクスポートする
いわさです。
AWS 上では様々なマネージドサービスを使ってアカウントやワークロードの問題点に気づき、改善することが出来ます。
例えば、AWS Trusted Advisor を使うと AWS 全般にわたるベストプラクティスへの適合状態を管理することが出来ます。以下のように自動でチェックしてくれた結果を確認することが出来ます。

こういったサービスが検出した内容をエクスポートして別のツールで管理したりした時があります。
Security Hub などの場合であれば CSV でダウンロードが可能なのですが、AWS Trusted Advisor の場合はダウンロードが可能ではあるのですがツールなどからは少し扱いにくい形式で出力されていました。
今回 JSON でチェック結果、推奨事項、推奨事項ごとのリソースをエクスポートするスクリプトを作成したので残しておきます。たまに使いたいときがあるので。
標準で提供されているダウンロード機能
まずは Trusted Advisor で使える標準のダウンロード機能を見てみましょう。
以下からダウンロードが可能です。少し時間がかかります。

これが CSV や JSON で出力できればそのデータを加工して使うとかしやすかったのですが、次のように EXCEL 形式で、かつ1シート1チェック項目で出力されます。

スクリプト
今回はまとまった構造で Trusted Advisor の情報を構造化されたデータとして確認したいと思っています。
Trusted Advisor では API が提供されており、どういったチェック項目があってどういう結果だったのかを API 経由で取得することも出来ます。これらの API を使ってデータを収集してみたいと思います。
今回はチェック項目をマスタとして取得するlist-checks、推奨事項一式を取得するlist-recommendations、推奨事項ごとに具体的にどのリソースで推奨事項が発生しているのかを取得するlist-recommendation-resourcesを使っていきたいと思います。
作成したスクリプトが以下になります。
#!/bin/bash
set -e
OUTPUT_FILE="trustedadvisor-results.json"
REGION="us-east-1"
echo "Trusted Advisor情報の収集を開始します..."
# チェック項目一覧を取得
echo "チェック項目一覧を取得中..."
CHECKS=$(aws trustedadvisor list-checks --language ja --region ${REGION} --output json)
# 全推奨事項を一括取得
echo "全推奨事項を一括取得中..."
ALL_RECOMMENDATIONS=$(aws trustedadvisor list-recommendations --region ${REGION} --output json)
# error/warningの推奨事項のARNを抽出
echo "リソース情報取得対象を抽出中..."
ERROR_WARNING_RECS=$(echo "${ALL_RECOMMENDATIONS}" | jq -r '.recommendationSummaries[] | select(.status == "error" or .status == "warning") | .arn')
# リソース情報を取得
RESOURCES_FILE="/tmp/ta_resources_$$.json"
echo "{}" > ${RESOURCES_FILE}
if [ -n "${ERROR_WARNING_RECS}" ]; then
REC_COUNT=$(echo "${ERROR_WARNING_RECS}" | wc -l | tr -d ' ')
echo "リソース情報取得対象: ${REC_COUNT}件"
CURRENT_REC=0
echo "${ERROR_WARNING_RECS}" | while read -r rec_arn; do
CURRENT_REC=$((CURRENT_REC + 1))
echo " [${CURRENT_REC}/${REC_COUNT}] リソース取得中..."
RESOURCES=$(aws trustedadvisor list-recommendation-resources \
--recommendation-identifier "${rec_arn}" \
--region ${REGION} \
--output json 2>/dev/null || echo '{"recommendationResourceSummaries":[]}')
# 一時ファイルに保存
TEMP_FILE="/tmp/ta_res_${CURRENT_REC}.json"
echo "${RESOURCES}" | jq --arg arn "${rec_arn}" '{($arn): .recommendationResourceSummaries}' > ${TEMP_FILE}
done
# 全リソース情報をマージ
jq -s 'reduce .[] as $item ({}; . * $item)' /tmp/ta_res_*.json > ${RESOURCES_FILE}
rm -f /tmp/ta_res_*.json
fi
# 結果を格納する配列を初期化
echo "[" > ${OUTPUT_FILE}
# チェック項目の数を取得
CHECK_COUNT=$(echo "${CHECKS}" | jq '.checkSummaries | length')
echo "チェック項目数: ${CHECK_COUNT}"
CURRENT=0
# 各チェック項目を処理
echo "${CHECKS}" | jq -c '.checkSummaries[]' | while read -r check; do
CURRENT=$((CURRENT + 1))
CHECK_ID=$(echo "${check}" | jq -r '.id')
CHECK_ARN=$(echo "${check}" | jq -r '.arn')
CHECK_NAME=$(echo "${check}" | jq -r '.name')
echo "[${CURRENT}/${CHECK_COUNT}] 処理中: ${CHECK_NAME}"
# このチェックの推奨事項を抽出(全フィールドを保持)
RECOMMENDATIONS=$(echo "${ALL_RECOMMENDATIONS}" | jq --arg arn "${CHECK_ARN}" --slurpfile resources ${RESOURCES_FILE} '
[.recommendationSummaries[] | select(.checkArn == $arn) |
. + (if ($resources[0][.arn] // null) != null then {resources: $resources[0][.arn]} else {} end)
]
')
# チェック項目の基本情報を構築(全フィールドを保持)
CHECK_ITEM=$(echo "${check}" | jq --argjson recs "${RECOMMENDATIONS}" '. + {recommendations: $recs}')
# 結果をファイルに追加
if [ ${CURRENT} -eq 1 ]; then
echo "${CHECK_ITEM}" >> ${OUTPUT_FILE}
else
echo ",${CHECK_ITEM}" >> ${OUTPUT_FILE}
fi
done
echo "]" >> ${OUTPUT_FILE}
# 一時ファイルを削除
rm -f ${RESOURCES_FILE}
echo "完了: ${OUTPUT_FILE} に保存しました"
実行結果
これを実行してみます。
% ./collect-trustedadvisor.sh
Trusted Advisor情報の収集を開始します...
チェック項目一覧を取得中...
全推奨事項を一括取得中...
リソース情報取得対象を抽出中...
リソース情報取得対象: 22件
[1/22] リソース取得中...
[2/22] リソース取得中...
[3/22] リソース取得中...
[4/22] リソース取得中...
[5/22] リソース取得中...
[6/22] リソース取得中...
[7/22] リソース取得中...
[8/22] リソース取得中...
[9/22] リソース取得中...
[10/22] リソース取得中...
[11/22] リソース取得中...
[12/22] リソース取得中...
[13/22] リソース取得中...
[14/22] リソース取得中...
[15/22] リソース取得中...
[16/22] リソース取得中...
[17/22] リソース取得中...
[18/22] リソース取得中...
[19/22] リソース取得中...
[20/22] リソース取得中...
[21/22] リソース取得中...
[22/22] リソース取得中...
チェック項目数: 538
[1/538] 処理中: IAM Access Analyzer - 外部アクセス
[2/538] 処理中: EC2 オンデマンドインスタンス
[3/538] 処理中: 漏洩したアクセスキー
[4/538] 処理中: Amazon EC2 リザーブドインスタンスのリース有効期限切れ
[5/538] 処理中: セキュリティグループ- 無制限アクセス
:
[533/538] 処理中: EBS プロビジョンド IOPS (SSD ボリューム集計 IOPS)
[534/538] 処理中: Route 53 再利用可能な委託セット
[535/538] 処理中: EBS スループット最適化 HDD (st1) ボリュームストレージ
[536/538] 処理中: Amazon EC2 アベイラビリティーゾーンのバランス
[537/538] 処理中: Classic Load Balancer セキュリティグループ
[538/538] 処理中: Amazon Aurora DB インスタンスアクセシビリティ
完了: trustedadvisor-results.json に保存しました
チェック項目一覧は一括で取得できるので一瞬で終わりますね。
推奨事項一覧自体も取得は一瞬で終わるのですが、推奨事項の対象リソースはそのアカウントごとの推奨事項の数だけ取得する必要があります。ここが少し時間かかります。
また、最後に取得済みのデータをチェック項目の数だけマージしているのでそこも処理時間が少しかかります。
私のアカウントでは1分もしないくらいで完了しました。
取得されたデータはこんな感じですね。
通常の API であればチェック項目の詳細情報と推奨事項の詳細情報を組み合わせて構造的に確認できないのですが、スクリプトで押し込みました。
これを元にツールで整形したりレポート化したり、AI とかに食わせやすいのではないでしょうか。

さいごに
本日は AWS Trusted Advisor の全件チェック結果をスクリプトでエクスポートしてみました。
探したのですが、良いエクスポート方法が地味になったのでスクリプトを作ってみました。
今後これを使って分析とか自動化とかしてみようかなと思ってます。







