Skip to content

Instantly share code, notes, and snippets.

@mizzy
Created May 16, 2025 01:33
Show Gist options
  • Save mizzy/581ccf2bd3b0e56d68d1c73de2d43e94 to your computer and use it in GitHub Desktop.
Save mizzy/581ccf2bd3b0e56d68d1c73de2d43e94 to your computer and use it in GitHub Desktop.
#!/bin/bash
# ログ出力用の関数(標準エラー出力に出力)
log() {
echo "$@" >&2
}
# 現在の日時を取得(1週間前の日時計算に使用)
current_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# 1週間前の日時を計算
one_week_ago=$(date -u -d "7 days ago" +"%Y-%m-%dT%H:%M:%SZ")
log "クォータ使用状況スキャンを開始します - $(date)"
log "期間: $one_week_ago から $current_date"
# JSON の開始を出力
echo "{"
first_service=true
# AWS service-quotas list-services を実行し、ServiceCode のリストを取得
log "サービスリストを取得中..."
service_codes=$(aws service-quotas list-services --query 'Services[*].ServiceCode' --output text)
service_count=$(echo "$service_codes" | wc -w)
log "合計 $service_count サービスをスキャンします"
# サービスカウンター
current_service=0
# 各 ServiceCode に対して処理を実行
for service_code in $service_codes; do
# カウンターを増やす
current_service=$((current_service + 1))
log "サービス $current_service/$service_count: $service_code を処理中..."
# サービスのクォータ情報を取得
quotas=$(aws service-quotas list-service-quotas --service-code "$service_code" --query 'Quotas[]')
# クォータ情報が空でなければ処理を続行
if [ "$quotas" != "[]" ] && [ "$quotas" != "" ]; then
# UsageMetric を持つクォータを検索
log " UsageMetric を持つクォータを検索中..."
usage_quotas=$(aws service-quotas list-service-quotas --service-code "$service_code" \
--query 'Quotas[?UsageMetric!=null].{QuotaName:QuotaName,QuotaCode:QuotaCode,Value:Value,Unit:Unit,UsageMetric:UsageMetric}' \
--output json)
# UsageMetric を持つクォータがある場合
if [ "$usage_quotas" != "[]" ] && [ "$usage_quotas" != "" ]; then
quota_count=$(echo "$usage_quotas" | jq 'length')
log " $quota_count 個のUsageMetricを持つクォータを発見"
# このサービスに有効なクォータがあるかどうかのフラグ
valid_quotas_found=false
active_quotas_array="["
first_quota=true
# 各クォータに対して処理
quota_index=0
while read -r quota; do
quota_index=$((quota_index + 1))
quota_name=$(echo "$quota" | jq -r '.QuotaName')
log " クォータ $quota_index/$quota_count: $quota_name を処理中..."
# UsageMetric 情報を取得
metric_namespace=$(echo "$quota" | jq -r '.UsageMetric.MetricNamespace')
metric_name=$(echo "$quota" | jq -r '.UsageMetric.MetricName')
metric_dimensions=$(echo "$quota" | jq -r '.UsageMetric.MetricDimensions')
log " メトリック情報: $metric_namespace:$metric_name"
# メトリック ID を生成(一意のIDを使用)
metric_id="m$(date +%s%N)"
# ディメンション情報を get-metric-data 用の形式に変換
dimensions_json="[]"
if [ "$(echo "$metric_dimensions" | jq 'length')" -gt 0 ]; then
dimensions_json="["
first=true
for key in $(echo "$metric_dimensions" | jq -r 'keys[]'); do
value=$(echo "$metric_dimensions" | jq -r ".[\"$key\"]")
if [ "$first" = true ]; then
first=false
else
dimensions_json="${dimensions_json},"
fi
dimensions_json="${dimensions_json}{\"Name\":\"$key\",\"Value\":\"$value\"}"
done
dimensions_json="${dimensions_json}]"
fi
# get-metric-data 用のメトリック JSON クエリを作成
metric_query="{\"Id\":\"$metric_id\",\"MetricStat\":{\"Metric\":{\"Namespace\":\"$metric_namespace\",\"MetricName\":\"$metric_name\",\"Dimensions\":$dimensions_json},\"Period\":3600,\"Stat\":\"Maximum\"}}"
# get-metric-data APIを使用して最大値を取得
log " CloudWatch からメトリックデータを取得中..."
max_usage_result=$(aws cloudwatch get-metric-data \
--start-time "$one_week_ago" \
--end-time "$current_date" \
--metric-data-queries "$metric_query" \
--output json)
# 結果から最大値を抽出(配列の中の最大値)
max_usage=$(echo "$max_usage_result" | jq -r ".MetricDataResults[0].Values | if length > 0 then max else \"N/A\" end")
log " 最大使用量: $max_usage"
# 最大使用量が0より大きい場合のみ追加
if [ "$max_usage" != "N/A" ] && [ "$max_usage" != "null" ] && (( $(echo "$max_usage > 0" | bc -l) )); then
log " 使用量が0より大きいため、JSONに追加します"
# クォータ名を配列に追加
if [ "$first_quota" = true ]; then
first_quota=false
else
active_quotas_array="${active_quotas_array},"
fi
# クォータ名をJSON文字列として追加(エスケープ処理)
quota_name_escaped=$(echo "$quota_name" | jq -R '.')
active_quotas_array="${active_quotas_array}${quota_name_escaped}"
valid_quotas_found=true
else
log " 使用量が0以下またはデータなしのため、スキップします"
fi
log ""
done < <(echo "$usage_quotas" | jq -c '.[]')
# クォータ配列を閉じる
active_quotas_array="${active_quotas_array}]"
# 有効なクォータが見つかった場合のみサービスを追加
if [ "$valid_quotas_found" = true ]; then
if [ "$first_service" = true ]; then
first_service=false
else
echo ","
fi
# サービスとそのクォータをJSONに追加(改行なし)
echo -n " \"$service_code\": $active_quotas_array"
log " サービス $service_code を JSONに追加しました"
else
log " サービス $service_code には使用量が0より大きいクォータがないため、スキップします"
fi
else
log " サービス $service_code には UsageMetric を持つクォータがありません"
fi
else
log " サービス $service_code にはクォータ情報がありません"
fi
log "----------------------------------------"
done
# JSON を閉じる
echo "}"
log "クォータスキャン完了 - $(date)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment