AWS OrganizationsのRCPクォータが倍増したので、2,000件の上限を確認してみた
はじめに
2026年7月22日、AWS Organizations のリソースコントロールポリシー(RCP)の組織あたり上限が1,000から2,000に引き上げられました。
| 項目 | 変更前 | 変更後 |
|---|---|---|
| RCP上限(組織あたり) | 1,000 | 2,000 |
RCPに関連するクォータとAPIレート制限です。
| 項目 | 値 |
|---|---|
| RCPポリシーサイズ上限 | 5,120文字 |
| RCPアタッチ上限(ルート/OU/アカウント各) | 5件(RCPFullAWSAccess含む) |
| CreatePolicy/DeletePolicy/AttachPolicy/DetachPolicy | rate 2/秒, burst 3 |
各クォータの詳細はドキュメントにまとまっています。
検証内容
検証環境
| 項目 | 値 |
|---|---|
| 実行元 | テスト用Organization管理アカウント |
| リージョン | us-east-1(Organizations APIエンドポイント) |
| CLI | AWS CLI v2(最新) |
| RCPポリシータイプ | 有効化済み |
| テスト用Organization | 全機能有効化済み、隔離環境 |
事前確認
検証開始時点の既存RCPはAWS管理ポリシーのRCPFullAWSAccessのみでした。作成したRCPはどこにもアタッチしていません。
作成するポリシーの内容
2,000件作成するRCPには、次の最小Denyステートメントを使用しました。存在しないリージョンxx-nonexistent-1を条件に指定しており、万一アタッチしても実際の操作に影響しない安全な内容です。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyNonexistentRegionNoOp",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "xx-nonexistent-1"
}
}
}
]
}
RCP 2,000件の作成
CreatePolicyのレート制限(rate 2/秒, burst 3)を踏まえ、1件あたり0.5秒のスリープとThrottlingException時の指数バックオフ(最大30秒)を組み込んだスクリプトで2,001件の作成を試みました。
作成用スクリプト全文
#!/usr/bin/env bash
# RCP 2,001件作成スクリプト(2,000件目まで成功→2,001件目でクォータエラーを期待)
set -uo pipefail
ARTICLE_DIR="/path/to/article"
POLICY_CONTENT="$ARTICLE_DIR/logs/rcp-policy-content.json"
RAW_DIR="$ARTICLE_DIR/logs/raw"
MILESTONE_LOG="$ARTICLE_DIR/logs/raw/milestones.log"
SUMMARY_LOG="$ARTICLE_DIR/logs/raw/create-loop-summary.tsv"
TOTAL=2001
START_INDEX=1
REGION="us-east-1"
echo -e "index\thttp_status_or_error\telapsed_ms\tpolicy_id\tthrottled_retries" > "$SUMMARY_LOG"
: > "$MILESTONE_LOG"
start_all=$(date +%s.%N)
throttle_count=0
for i in $(seq $START_INDEX $TOTAL); do
name="rcp-quota-test-$(printf '%04d' "$i")"
backoff=1
retries=0
t0=$(date +%s.%N)
while true; do
out=$(aws organizations create-policy \
--name "$name" \
--description "RCP quota test policy #$i" \
--type RESOURCE_CONTROL_POLICY \
--content "file://$POLICY_CONTENT" \
--region "$REGION" \
--output json 2>&1)
rc=$?
if [ $rc -eq 0 ]; then
break
fi
if echo "$out" | grep -q "ThrottlingException\|TooManyRequestsException"; then
throttle_count=$((throttle_count+1))
retries=$((retries+1))
sleep "$backoff"
backoff=$((backoff * 2))
if [ $backoff -gt 30 ]; then backoff=30; fi
continue
else
# 別のエラー(クォータ超過等)→ ループを抜けて記録
break
fi
done
t1=$(date +%s.%N)
elapsed_ms=$(awk "BEGIN {printf \"%.0f\", ($t1 - $t0) * 1000}")
if [ $rc -eq 0 ]; then
policy_id=$(echo "$out" | grep -o '"Id": "p-[^"]*"' | head -1 | sed 's/"Id": "//;s/"//')
echo -e "${i}\tSUCCESS\t${elapsed_ms}\t${policy_id}\t${retries}" >> "$SUMMARY_LOG"
echo "$out" > "$RAW_DIR/create-$(printf '%04d' "$i").json"
else
echo -e "${i}\tERROR\t${elapsed_ms}\t-\t${retries}" >> "$SUMMARY_LOG"
echo "$out" > "$RAW_DIR/create-$(printf '%04d' "$i")-error.json"
echo "[$i] ERROR: $out" >> "$MILESTONE_LOG"
fi
if [ "$i" -eq 1000 ]; then
echo "[MILESTONE] 1000件目 index=$i rc=$rc elapsed_ms=$elapsed_ms" >> "$MILESTONE_LOG"
fi
if [ "$i" -eq 1001 ]; then
echo "[MILESTONE] 1001件目(旧上限突破) index=$i rc=$rc elapsed_ms=$elapsed_ms" >> "$MILESTONE_LOG"
fi
if [ "$i" -eq 2000 ]; then
echo "[MILESTONE] 2000件目(新上限到達) index=$i rc=$rc elapsed_ms=$elapsed_ms" >> "$MILESTONE_LOG"
fi
if [ "$i" -eq 2001 ]; then
echo "[MILESTONE] 2001件目(想定エラー) index=$i rc=$rc elapsed_ms=$elapsed_ms" >> "$MILESTONE_LOG"
fi
# rate 2/秒, burst 3 を踏まえた基本スリープ
sleep 0.5
done
end_all=$(date +%s.%N)
total_elapsed=$(awk "BEGIN {printf \"%.1f\", ($end_all - $start_all)}")
echo "[SUMMARY] total_elapsed_sec=$total_elapsed throttle_count=$throttle_count" >> "$MILESTONE_LOG"
echo "DONE total_elapsed_sec=$total_elapsed throttle_count=$throttle_count"
| マイルストーン | index | 結果 | elapsed_ms |
|---|---|---|---|
| 1,000件目作成 | 1000 | 成功 | 1187 |
| 1,001件目作成(旧上限1,000突破) | 1001 | 成功 | 1158 |
| 2,000件目作成(新上限到達) | 2000 | 成功 | 1149 |
| 2,001件目作成(想定エラー) | 2001 | 失敗 | 1047 |
本検証環境では個別のクォータ引き上げ申請を行っていません。申請なしで1,000件を超えて作成でき、2,000件目まで成功したことから、本検証環境では新しい上限が有効になっていることを確認できました。
2,001件目のエラー確認
2,001件目では次のエラーが返りました。
An error occurred (ConstraintViolationException) when calling the CreatePolicy operation:
You have exceeded the allowed number of policies.
Additional error details:
Reason: POLICY_NUMBER_LIMIT_EXCEEDED
2,000件目の作成が成功し、2,001件目でこのエラーが返ったことから、組織あたりのカスタムRCP上限が2,000件であると確認できます。
この時点でlist-policies --filter RESOURCE_CONTROL_POLICYの全件数は、カスタムRCP 2,000件+AWS管理ポリシー(RCPFullAWSAccess)1件=合計2,001件でした。この結果から、組織あたり2,000件の作成上限ではRCPFullAWSAccessはカウントされない挙動と判断できます。
スロットリングの実測
実測値は次のとおりです。
| 項目 | 値 |
|---|---|
| スロットリング発生回数 | 0回 |
| 1件あたりの平均応答時間 | 約1.1〜1.2秒 |
| ループ内スリープ | 0.5秒/件固定(バックオフ発動なし) |
| 総所要時間(2,001件試行) | 3,314.1秒(約55分14秒) |
| 実効スループット | 約0.60件/秒 |
今回は逐次実行でAPI応答に約1.1秒を要したため、0.5秒の固定スリープを加えた実際のリクエスト間隔は約1.6秒となりました。この条件ではスロットリングは発生しませんでした。大量作成の所要時間は(APIレイテンシ+スリープ)×件数が目安になります。
クリーンアップ
検証完了後、作成した2,000件のRCP(RCPFullAWSAccessを除く)をすべて削除しました。
まとめ
RCPの上限が2,000件に拡張されたことで、OU・アカウント・保護対象リソースごとに、より細かなガードレールを設計できる余地が広がりました。
ただし、上限までポリシー数を増やした場合、維持更新に必要な時間も無視できません。本検証では逐次作成で約0.60件/秒となっており、2,000件規模の処理は短時間では完了しません。更新処理でも同様に、APIの応答時間やOrganizations APIのレート制限を考慮した実行計画が必要になります。
並列度を上げた場合の性能やスロットリングの挙動は本記事では検証していません。そのため、2,000件という上限値を前提にした設計を始める際は、ポリシー数だけでなく、全件更新・段階的な変更・緊急時の修正をどの程度の時間で実施できるかを事前に評価するのがよさそうです。
RCPのポリシー数の上限は増えましたが、すべての制御をRCPに集約するのではなく、SCPなども含め、それぞれの用途・更新頻度・管理コストに応じて適切に組み合わせた利用をご検討ください。








