「本番環境と開発環境でアカウントを分けたいが、セキュリティポリシーをどう統一すればいいかわからない」
AWSを本格的に使い始めると、こうした壁にぶつかります。アカウントが1つのうちは管理できても、チームが拡大し、プロジェクトが増えると、単一アカウントでは権限管理・コスト管理・セキュリティ統制に限界が来ます。
この記事では、AWS Organizationsを使ったマルチアカウント設計の基本を解説します。OU(組織単位)による階層設計、SCP(サービスコントロールポリシー)を使った全アカウントへのガードレール適用、Consolidated Billing(一括請求)によるコスト一元管理まで、実際のコマンド出力例を交えて体系的に説明します。
実行環境: AWS マネジメントコンソールおよびAWS CLI v2(aws-cli/2.15.30 on Amazon Linux 2023)で動作確認済み。
この記事のポイント
・AWS OrganizationsはOU(組織単位)でアカウントを階層管理し、SCP(サービスコントロールポリシー)で全体統制する
・SCPはIAMポリシーの上位にある制御層で、AdministratorAccessでも突破できないガードレールを作れる
・OU設計は「本番/開発/セキュリティ/サンドボックス」の4層分離が実務の標準パターン
・Consolidated Billingで全アカウントのコストを一元集計し、RIの割引も組織全体で共有される
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
AWS Organizationsとは何か|マルチアカウント管理を一元化する仕組み
AWS Organizationsは、複数のAWSアカウントを1つの「組織(Organization)」にまとめて管理するサービスです。2017年にGAとなり、現在では大規模なAWS環境の標準的なガバナンス基盤として位置づけられています。Organizationsの3つの主機能はそれぞれ独立しながら補い合います。
・OU(Organizational Unit): アカウントをグループ化する階層構造。本番/開発/テストなど用途別に分類し、ポリシーを継承させる
・SCP(Service Control Policy): OU/アカウント単位でAWSサービスの利用を制限するポリシー。IAMより上位の制御層として機能する
・Consolidated Billing: 全アカウントの請求を管理アカウントに統合。リザーブドインスタンスの割引を組織全体で共有できる
1. マルチアカウント設計が必要になる理由
単一アカウント運用の限界は、規模が拡大するにつれて顕在化します。| 課題 | 単一アカウント | マルチアカウント(Organizations) |
|---|---|---|
| 本番/開発の分離 | IAMポリシーのみで分離(設定ミスで本番に影響する) | アカウント境界で物理的に完全分離される |
| セキュリティポリシー適用 | アカウントごとに個別設定(抜け漏れが発生しやすい) | SCPで全アカウントに強制適用できる |
| コスト管理 | タグ管理に依存(タグ付け漏れで不明コストが出る) | アカウント単位で自動集計・部門別請求が明確になる |
| 障害の影響範囲 | 誤操作が全環境に波及するリスクがある | アカウント境界で影響を封じ込められる |
2. 管理アカウントとメンバーアカウントの役割
Organizations内のアカウントは2種類に分かれます。・管理アカウント(旧: マスターアカウント): Organizationsを作成したアカウント。SCPの作成・適用、メンバーアカウントの招待・作成、Consolidated Billingの管理を担う。業務作業には使わない専用アカウントとして運用することが鉄則
・メンバーアカウント: 組織に参加している通常のAWSアカウント。各環境(本番/開発/セキュリティ等)ごとに作成する
管理アカウントを業務用に使ってしまうのが最もよくある失敗パターンです。管理アカウントにはSCPが適用されないため、セキュリティポリシーの抜け穴になります。専用アカウントとして完全に分離してください。
AWS Organizationsのセットアップ|組織の作成とアカウント追加手順
1. 組織を作成する
管理アカウントでOrganizationsを有効化します。「All features」モードを選択することでSCPが利用できます。「Consolidated Billing only」モードを選んでしまうとSCPが使えないため、必ずAll featuresを指定してください。# 組織を作成する(All featuresモード) aws organizations create-organization --feature-set ALL
# 出力例 { "Organization": { "Id": "o-exampleorgid11", "Arn": "arn:aws:organizations::111122223333:organization/o-exampleorgid11", "FeatureSet": "ALL", "MasterAccountId": "111122223333", "MasterAccountEmail": "management@example.com", "AvailablePolicyTypes": [ { "Type": "SERVICE_CONTROL_POLICY", "Status": "ENABLED" } ] } }
2. 現在のアカウント一覧とルートIDを確認する
# 全アカウント一覧を確認する aws organizations list-accounts --query 'Accounts[*].[Id,Name,Status]' --output table # 出力例 ------------------------------------------------------ | ListAccounts | +----------------+------------------+----------------+ | 111122223333 | management | ACTIVE | | 444455556666 | production | ACTIVE | | 777788889999 | development | ACTIVE | +----------------+------------------+----------------+ # ルートIDを確認する(OU作成時に必要) aws organizations list-roots --query 'Roots[*].[Id,Name]' --output table # 出力例 ---------------------------------------------- | ListRoots | +------------------+-------------------------+ | r-ab12 | Root | +------------------+-------------------------+
3. Organizations経由で新規アカウントを作成する
Organizations経由でAWSアカウントを作成すると、自動的に組織のメンバーになります。作成には数分かかるためcreate-account-statusで進捗を確認します。# 新規アカウントを作成する aws organizations create-account --email sandbox-team@example.com --account-name "sandbox" # 出力例(作成中の状態) { "CreateAccountStatus": { "Id": "car-examplecreaterequestid111", "AccountName": "sandbox", "State": "IN_PROGRESS", "RequestedTimestamp": "2026-07-01T09:00:00.000000+09:00" } } # 作成完了を確認する aws organizations describe-create-account-status --create-account-request-id car-examplecreaterequestid111 # 出力例(完了後) { "CreateAccountStatus": { "Id": "car-examplecreaterequestid111", "AccountName": "sandbox", "State": "SUCCEEDED", "AccountId": "000011112222" } }
OU(組織単位)設計の基本|アカウントを階層で整理する方法
OUは組織のルートの下に複数作成できる階層構造です。OUに対してSCPを付与すると、配下のすべてのアカウントにポリシーが自動継承されます。1. 実務で使うOU設計の標準パターン
これまで複数の企業のAWSマルチアカウント設計に携わった中で、以下のような4層分離が実務標準として機能しています。| OU名 | 配置するアカウント | 適用するSCPの例 |
|---|---|---|
| Production | 本番環境アカウント | リージョン制限、デプロイ権限のみ許可 |
| Development | 開発・ステージング環境 | リージョン制限のみ(開発者に幅広い権限) |
| Security | ログ集約・セキュリティ監査用 | CloudTrailログの削除を禁止 |
| Sandbox | 個人学習・検証用 | コスト上限(Budgets)、高額サービス禁止 |
2. OUを作成してアカウントを移動する
# ルート直下にProductionOUを作成する(--parent-idにルートIDを指定) aws organizations create-organizational-unit --parent-id r-ab12 --name Production # 出力例 { "OrganizationalUnit": { "Id": "ou-ab12-exampleouid111", "Arn": "arn:aws:organizations::111122223333:ou/o-exampleorgid11/ou-ab12-exampleouid111", "Name": "Production" } } # アカウントをProductionOUへ移動する # --source-parent-idは現在の親(未分類の場合はルートID) aws organizations move-account --account-id 444455556666 --source-parent-id r-ab12 --destination-parent-id ou-ab12-exampleouid111 # OU配下のアカウントを確認する aws organizations list-accounts-for-parent --parent-id ou-ab12-exampleouid111 --query 'Accounts[*].[Id,Name]' --output table
SCP(サービスコントロールポリシー)で全アカウントを統制する
SCPはOrganizationsの最も重要な機能です。SCPはIAMポリシーよりも上位の制御層として機能し、SCPで拒否した操作はAdministratorAccessを持つIAMユーザーでも実行できません。この「突破できない壁」こそが、マルチアカウント統制の核心です。1. SCPとIAMポリシーの違いを正確に理解する
SCPは「許可の上限」を設定するものです。IAMポリシーが「その主体が何できるか」を定義するのに対して、SCPは「そのアカウントで何を上限とするか」を組織レベルで強制します。| 項目 | IAMポリシー | SCP |
|---|---|---|
| 適用対象 | IAMユーザー・グループ・ロール | OUまたはAWSアカウント全体 |
| 制御の性質 | 何ができるかを定義する(Allow/Deny) | 最大で何ができるかの上限を設定する |
| 適用先 | 特定の主体(ユーザー等) | アカウント内の全IAMエンティティ |
| 管理アカウントへの適用 | 適用される | 適用されない(管理アカウントは除外) |
| 優先度 | SCPの範囲内でのみ有効 | IAMポリシーより上位(最終的な上限) |
2. 実践的なSCPの設定例(リージョン制限)
最もよく使うSCPの1つが、利用リージョンを東京(ap-northeast-1)に限定するポリシーです。GDPR対応・社内ガバナンス・コスト管理のために必須の設定です。# scp-deny-regions.json(ap-northeast-1以外を拒否するSCP) cat << 'EOF' > /tmp/scp-deny-regions.json { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyOutsideApNortheast1", "Effect": "Deny", "NotAction": [ "iam:*", "organizations:*", "route53:*", "budgets:*", "support:*", "sts:*", "cloudfront:*", "waf:*" ], "Resource": "*", "Condition": { "StringNotEquals": { "aws:RequestedRegion": "ap-northeast-1" } } } ] } EOF # SCPをOrganizationsに作成する aws organizations create-policy --content file:///tmp/scp-deny-regions.json --description "ap-northeast-1以外のリージョン利用を禁止" --name DenyNonApNortheast1 --type SERVICE_CONTROL_POLICY # 出力例 { "Policy": { "PolicySummary": { "Id": "p-examplescpid111", "Name": "DenyNonApNortheast1", "Type": "SERVICE_CONTROL_POLICY" } } } # SCPをProductionOUにアタッチする aws organizations attach-policy --policy-id p-examplescpid111 --target-id ou-ab12-exampleouid111
3. rootユーザー操作を禁止するSCP
メンバーアカウントのrootユーザーによる操作を禁止するSCPも、セキュリティ統制の基本です。rootアカウントを封じることで、アカウントへの不正アクセスが発生してもrootによる破壊的な操作を防げます。# scp-deny-root.json(rootユーザー操作禁止SCP) cat << 'EOF' > /tmp/scp-deny-root.json { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyRootAccess", "Effect": "Deny", "Action": "*", "Resource": "*", "Condition": { "StringLike": { "aws:PrincipalArn": "arn:aws:iam::*:root" } } } ] } EOF aws organizations create-policy --content file:///tmp/scp-deny-root.json --description "メンバーアカウントのrootユーザー操作を禁止" --name DenyRootAccess --type SERVICE_CONTROL_POLICY
# OUにアタッチされているポリシー一覧を確認する aws organizations list-policies-for-target --target-id ou-ab12-exampleouid111 --filter SERVICE_CONTROL_POLICY --query 'Policies[*].[Id,Name]' --output table # 出力例(実サーバー確認済み) ------------------------------------------------- | ListPoliciesForTarget | +------------------------+----------------------+ | p-examplescpid111 | DenyNonApNortheast1 | | p-examplescpid222 | DenyRootAccess | +------------------------+----------------------+
一括請求(Consolidated Billing)でコストを可視化する
Consolidated Billingは、Organizationsを有効にした時点で自動的に有効になります。全メンバーアカウントの請求が管理アカウントに統合され、アカウント別・サービス別のコスト分析が可能になります。1. Consolidated Billingの主なメリット
・コストの一元管理: AWS Cost Explorerで全アカウントのコストをアカウント別・サービス別に確認できる・ボリュームディスカウント: 組織全体のS3ストレージ・データ転送量を合計して割引階層を適用するため、個別アカウントより安くなる
・リザーブドインスタンスの共有: 管理アカウントで購入したEC2 RIを組織全体で共有できる(デフォルトで有効)
# 今月のアカウント別コストを確認する(AWS CLI) aws ce get-cost-and-usage --time-period Start=2026-07-01,End=2026-07-11 --granularity MONTHLY --metrics "BlendedCost" --group-by Type=DIMENSION,Key=LINKED_ACCOUNT --query 'ResultsByTime[0].Groups[*].[Keys[0],Metrics.BlendedCost.Amount]' --output table # 出力例 --------------------------------------- | GetCostAndUsage | +----------------+--------------------+ | 111122223333 | 12.34 | | 444455556666 | 245.67 | | 777788889999 | 89.10 | +----------------+--------------------+
2. アカウント別の予算アラートを設定する
各メンバーアカウントにBudgetsアラートを設定することで、想定外のコスト増加を早期に検知できます。特にSandbox OUのアカウントでは必須の設定です。# サンドボックスアカウント(000011112222)で月50ドル超過アラートを設定する # (メンバーアカウントのCLI環境で実行、またはaws stsでロール切り替え後に実行) aws budgets create-budget --account-id 000011112222 --budget '{ "BudgetName": "sandbox-monthly-limit", "BudgetLimit": {"Amount": "50", "Unit": "USD"}, "BudgetType": "COST", "TimeUnit": "MONTHLY" }' --notifications-with-subscribers '[{ "Notification": { "NotificationType": "ACTUAL", "ComparisonOperator": "GREATER_THAN", "Threshold": 80 }, "Subscribers": [{"SubscriptionType": "EMAIL", "Address": "admin@example.com"}] }]'
マルチアカウント統制の設計パターン|ガードレールの考え方
ここまでの機能を組み合わせた、実践的な統制設計のパターンを解説します。1. 予防的ガードレールと発見的ガードレールの使い分け
統制設計には2種類のアプローチがあります。| 種類 | 手段 | 特徴 |
|---|---|---|
| 予防的ガードレール | SCP(Deny) | 問題のある操作を事前にブロックする。確実だが柔軟性が低い |
| 発見的ガードレール | AWS Config・CloudTrail・Security Hub | 違反を検知してアラートを出す。柔軟だが事後対応になる |
2. OU別のSCP設計指針
各OUへのSCP設計では、「そのOUのアカウントでやってはいけないこと」を明確にするのが出発点です。・Production OU: リージョン制限・rootアクセス禁止・IAMユーザー作成禁止(ロールのみ許可)を最低限設定する
・Development OU: リージョン制限のみ。開発者がインフラを自由に試せる環境を確保する
・Security OU: CloudTrailログの削除禁止・CloudWatch Logs削除禁止を適用する
・Sandbox OU: 高額サービス(Reserved Instance購入・Savings Plans)の購入禁止を追加する
3. 組織全体の共通SCP(ルートにアタッチ)
以下のSCPはルート(Root)に直接アタッチして全アカウントに適用することを推奨します。# CloudTrailの無効化・ログ削除を組織全体で禁止するSCP例 { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyCloudTrailDisable", "Effect": "Deny", "Action": [ "cloudtrail:DeleteTrail", "cloudtrail:StopLogging", "cloudtrail:UpdateTrail" ], "Resource": "*" } ] }
トラブルシュート|SCPが効かない・操作が失敗するときの対処法
SCPを設定したのに制限が効かない場合
SCPを設定しても想定どおりに制限が効かない場合、以下の原因が多いです。・管理アカウントで操作している: 管理アカウントにはSCPが適用されません。意図的な仕様です
・FullAWSAccess SCPが上書きしている: Organizationsのデフォルトで「FullAWSAccess」というSCPが全OUにアタッチされています。これを削除しないとDenyが機能しない場合があります
・NotActionの書き方が誤っている: リージョン制限SCPでNotActionに含めるべきグローバルサービスが漏れているとDenyが意図しない範囲に及ぶ
# OUにアタッチされている全SCPを確認する aws organizations list-policies-for-target --target-id ou-ab12-exampleouid111 --filter SERVICE_CONTROL_POLICY # FullAWSAccessが余分にアタッチされている場合はデタッチする aws organizations detach-policy --policy-id p-FullAWSAccess --target-id ou-ab12-exampleouid111 # IAM Policy Simulatorでの権限確認(マネジメントコンソール) # IAM → ポリシーシミュレーター → 対象ユーザーとアクションを指定して確認
アカウント招待(Inviteメール)が届かない場合
既存アカウントを組織に招待した場合、招待メールはそのアカウントのrootメールアドレスに送信されます。・招待メールはrootメールアドレスに届くため、業務用メールとは別のアドレスが登録されていることが多い
・招待の有効期限は15日間。期限切れの場合は再招待が必要
・Organizations側での招待確認: aws organizations list-handshakes-for-organization
# 送信済みの招待状況を確認する aws organizations list-handshakes-for-organization --filter ActionType=INVITE --query 'Handshakes[*].[Id,State,ExpirationTimestamp]' --output table # 出力例 ---------------------------------------------------------- | ListHandshakesForOrganization | +-------------------+------------+----------------------+ | h-examplehandshk1 | OPEN | 2026-07-26T09:00:00 | +-------------------+------------+----------------------+
本記事のまとめ
AWS Organizationsによるマルチアカウント設計の要点をまとめます。| やりたいこと | 使う機能・コマンド |
|---|---|
| 組織を作成する | aws organizations create-organization --feature-set ALL |
| OUを作成する | aws organizations create-organizational-unit --parent-id r-xxxx --name OU名 |
| アカウントをOUへ移動する | aws organizations move-account --account-id xxx --source-parent-id xxx --destination-parent-id xxx |
| SCPを作成する | aws organizations create-policy --content file://scp.json --type SERVICE_CONTROL_POLICY |
| SCPをOUにアタッチする | aws organizations attach-policy --policy-id p-xxx --target-id ou-xxx |
| アカウント別コストを確認する | aws ce get-cost-and-usage + LINKED_ACCOUNTグループ |
AWSのマルチアカウント設計を含むインフラ構築を体系的に学びたい方は、AWSマスターセミナーの学習ロードマップもあわせてご覧ください。
Linux無料マニュアルを受け取る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます