More than 90% of DOP-C02 exam questions assume a multi-account environment as the baseline. Scenarios that begin "a company operates separate prod, staging, and dev accounts..." appear endlessly. Without this foundation, the topics that follow — cross-account deployment, centralized security, StackSets — are all left floating in mid-air.
Today we cover why multi-account became the standard, and how AWS Organizations, Control Tower, and IAM Identity Center build that foundation.
When first adopting AWS, most start with a single account, separating dev/staging/prod with VPCs and IAM. But as the company grows, almost every company moves to multi-account. Why?
In a single account, what happens if an operator accidentally fires a command like aws s3 rb --force at a prod bucket? IAM can block it, but it is powerless when someone who has the permission makes a mistake. With separate accounts, the explicit extra step of an STS AssumeRole is required, lowering the chance of a mistake.
📚 Case study: In 2017, a GitLab SRE operating the prod DB ran an
rm -rfcommand on prod believing it was the staging environment. 300GB of the prod DB was wiped out entirely, and because backups weren't working properly, six hours of data was lost. GitLab subsequently began separating prod/staging into distinct accounts. The same kind of incident has repeated countless times in AWS environments, and this is the starting point of multi-account strategy.
AWS Service Quotas (formerly Limits) are per-account. If the EC2 instance limit is 1,000 in a single account and the dev team burns through all 1,000, prod can't launch new instances. Separate the accounts and each gets its own 1,000.
Cost Allocation Tags alone have limits. To see precisely "how much did the Marketing team spend this month," splitting by account is far clearer. AWS Organizations + Consolidated Billing provides this foundation.
Click a choice to reveal the answer and explanation.
Question 1
A company running dev, staging, and prod environments in a single AWS account is moving to multi-account. What is the most essential reason?
Question 2
What is the essential characteristic that distinguishes an SCP from an IAM policy?
Question 3
A company is building multi-account CI/CD. Where should the pipeline live?
Question 4
Of the three mechanisms for cross-account resource access, which scenario best fits RAM (Resource Access Manager)?
Question 5
What is the essential advantage of an Organization Trail?
Question 6
Why does ExternalId go into a cross-account role's trust policy?
Question 7
Which three accounts are created automatically by Control Tower's Landing Zone?
Question 8
A company applied an SCP to "block all AWS operations outside the ap-northeast-2 region," and then IAM users could no longer create IAM policies in the console. What is the cause?
Regulations like PCI-DSS, HIPAA, and FedRAMP require "isolating production workloads from other environments." IAM separation alone rarely satisfies auditors; a separate account is the most definitive isolation.
IAM policies struggle to express complex cross-team permissions. Using the account itself as the boundary reduces permission management to the simple model of "who can enter this account."
💡 Related theory: The essence of multi-account strategy is the bulkhead pattern. Made famous by the Resilience4j library, this pattern isolates components so that one component's failure doesn't propagate to others. Like a ship's bulkheads: even if one compartment floods, the others survive. An AWS account is the cloud-infrastructure version of that.
AWS Organizations (launched 2017) is the service that manages multiple AWS accounts as a single entity. Core components:
| Element | Meaning |
|---|---|
| Management Account | The organization's root account. Manages Organizations itself. |
| Member Account | A regular account belonging to the organization |
| OU (Organizational Unit) | A grouping of accounts. Tree structure (up to depth 5) |
| SCP (Service Control Policy) | Permission guardrails applied to OUs/accounts (deny-only) |
| Consolidated Billing | Aggregates all member account billing into the management account |
Root
├── Security OU
│ ├── Log Archive Account (CloudTrail, Config log aggregation)
│ └── Security Tooling Account (GuardDuty, Security Hub administrator)
├── Infrastructure OU
│ ├── Network Account (Transit Gateway, Direct Connect)
│ └── Shared Services Account (DNS, AD, CI/CD)
├── Workloads OU
│ ├── Prod OU
│ │ ├── Prod-App-A Account
│ │ └── Prod-App-B Account
│ ├── Non-Prod OU
│ │ ├── Staging Account
│ │ └── Dev Account
└── Sandbox OU (personal experimentation)
This structure is the AWS-recommended best practice. When the exam presents a "which account should this go in" scenario, answer with this pattern as the baseline.
🔍 Going deeper: An SCP is a policy that only has effect on deny. Even if an SCP says
Allow, that alone grants no permission — it means the SCP "permits" what IAM policies already grant. The real power of SCPs isDeny. For example,Deny ec2:RunInstances if region != ap-northeast-2forces every account in that OU to be unable to launch EC2 outside the Seoul region. No matter how broad the IAM permissions, if the SCP blocks it, it cannot be done.
AWS permission evaluation happens in this order:
An explicit Deny anywhere in this chain means rejection; the request must pass all of them and have an Allow somewhere to be permitted.
⚠️ Pitfall: A common confusion is "I created an Allow policy in the SCP but it still doesn't work." An SCP is a guardrail, not a permission grant. Even if the SCP says Allow, permissions must be granted separately in IAM. Exam options like "granting permissions with SCP alone" are traps.
AWS Control Tower (launched 2019) is a landing zone service that sets up Organizations + IAM Identity Center + Config + CloudTrail + ... all at once. Use it when you want to "start with a best-practice OU structure from day one."
| Capability | Description |
|---|---|
| Landing Zone | Standard OU structure + automatic creation of security accounts |
| Account Factory | Self-service creation of new accounts (based on Service Catalog) |
| Guardrails | Automatic application of preventive (SCP) + detective (Config Rule) controls |
| Customizations for Control Tower (CfCT) | Additional customization via CloudFormation |
Control Tower's core trade-off:
📚 Case study: A large enterprise spent six months trying to consolidate 50 existing AWS accounts into Control Tower. Existing SCPs, CloudTrail trails, and IAM policies conflicted with Control Tower's standards, making migration extremely complex. Lesson: if you already run multi-account, a PoC is mandatory before deciding to adopt Control Tower. For greenfield adoption, starting with Control Tower is much faster.
Accounts Control Tower creates automatically:
And the OU structure:
Control Tower guardrails come in two kinds:
Each guardrail is classified as mandatory, strongly recommended, or elective. New accounts get mandatory guardrails applied automatically.
🔍 Going deeper: The preventive-vs-detective trade-off is "automatability vs side effects." Preventive (SCP) blocks the action itself, so incident prevention is guaranteed, but a badly written one blocks legitimate work too (e.g., blocking all root logins — including emergency access). Detective detects after the fact, so side effects are fewer, but the incident has already happened. In practice: preventive for critical, detective for monitoring-grade concerns.
Formerly named AWS Single Sign-On (SSO), it was renamed IAM Identity Center in 2022. The core capability: "one login for access to all your accounts."
[ IAM Identity Center flow ]
User → Identity Provider (Okta/AzureAD/AWS Directory)
|
↓ SAML/SCIM
IAM Identity Center (installed in the organization's management account)
|
↓ AssumeRole (automatic)
Permission Set Role in the Member Account
From the user's perspective, logging in at https://.awsapps.com/start shows cards for every account+role they can access; clicking one enters that account's console. For the CLI, aws sso login obtains a token.
💡 Related theory: IAM Identity Center is essentially AssumeRole automation. When the user clicks a card, IAM Identity Center calls STS AssumeRole, obtains temporary credentials, and launches the console/CLI with them. Because all credentials are temporary (typically 1 to 12 hours), it is far safer than static IAM users.
| Dimension | IAM User (traditional) | IAM Identity Center |
|---|---|---|
| Credentials | Static access keys | Temporary STS |
| Multi-account | Separate user per account | One user for all accounts |
| External IdP integration | SAML federated users | SCIM + SAML automatic |
| Password rotation | User's responsibility | Follows IdP policy |
| Exam frequency | Steadily decreasing | Steadily increasing |
AWS explicitly recommends "use IAM Identity Center for new workloads." On the exam, "multi-account + SSO" scenarios almost always have IAM Identity Center as the answer.
⚠️ Pitfall: The misconception that "with IAM Identity Center, you no longer need IAM." Human users move to IAM Identity Center, but machine principals (EC2, Lambda, ECS tasks) still use IAM Roles. IAM is not going away.
The heart of multi-account is "how does one account access resources in another account." There are three patterns.
[ Cross-Account AssumeRole ]
Account A (CI/CD) Account B (Prod)
IAM User/Role ──AssumeRole──→ CrossAccountRole
(sts:AssumeRole) (trust policy: Account A)
(permission: ECS deploy)
Account B's role explicitly states "trust Account A's ARN" in its trust policy. Account A's principal calls sts:AssumeRole to obtain temporary credentials and access Account B's resources.
# Example cross-account role trust policy in Account B
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::ACCOUNT_A_ID:role/CICDPipelineRole"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"sts:ExternalId": "unique-secret-id"}
}
}]
}ExternalId is for preventing the confused deputy problem. It is especially important when integrating with external SaaS (e.g., when Datadog or PagerDuty enters your account).
💡 Related theory: The confused deputy problem is a security issue discovered by Norm Hardy in 1988 — a vulnerability where "a privileged deputy performs an unprivileged party's request using its own privileges." In AWS, when integrating a SaaS, the SaaS's AWS account becomes the deputy accessing your resources;
ExternalIdprovides isolation so that other customers of the same SaaS cannot access your resources through it.
S3 buckets, SNS topics, and KMS keys can carry policies attached to the resource itself, explicitly allowing principals from other accounts.
// S3 bucket policy example (Account B's bucket allows Account A access)
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::ACCOUNT_A_ID:root"},
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::shared-bucket/*"
}]
}Cross-account access is possible even without AssumeRole. However, only some services support it — S3, SNS, SQS, KMS, Lambda, and a few others.
Some resources — VPCs, Subnets, Transit Gateways, License Manager — can be shared with other accounts via RAM. On the exam it frequently appears in "share a Transit Gateway across multiple accounts" scenarios.
CloudTrail is per-account by default, but with an Organization Trail, the management account captures the API calls of every member account at once and stores them in a single S3 bucket. The Log Archive account is that bucket's owner.
[ Organization Trail flow ]
All Member Accounts → CloudTrail Events → Organization Trail →
→ S3 Bucket in the Log Archive Account (immutable, MFA delete)
→ CloudWatch Logs (optional)
→ EventBridge (optional)
The essence of this architecture:
📚 Case study: During an internal audit, a company investigated "who changed the prod IAM policies in the last three months," but each member account stored its CloudTrail separately, so manually collecting logs from 30 accounts took a week. After switching to an Organization Trail + Log Archive account, the same query finished in 10 minutes with Athena.
The most common multi-account CI/CD topology:
[ Hub-Spoke model ]
Shared Services Account (Hub)
- CodeCommit / GitHub
- CodeBuild
- CodePipeline (orchestrator)
- ECR (shared image registry)
- S3 (artifact bucket, KMS encrypted)
|
├─AssumeRole──→ Dev Account (Spoke)
│ - ECS/Lambda deployment target
│ - CrossAccountDeployRole
|
├─AssumeRole──→ Staging Account
│ - same pattern
|
└─AssumeRole──→ Prod Account
- deploy after manual approval
- CrossAccountDeployRole (restricted)
Core security principles:
🎯 Scenario: The exam frequently asks, "a company runs separate dev/staging/prod accounts — where should CodePipeline live?" The answer: "in a separate Shared Services account, deploying into each environment account via AssumeRole." Putting a prod-only pipeline inside the prod account means ① the prod account's permissions become too powerful ② consistency across environments breaks ③ change management gets fragmented. Hub-Spoke is the standard.
Frequently used SCP examples:
// 1. Allow operations only in specific regions
{
"Effect": "Deny",
"NotAction": [
"iam:*", "organizations:*", "cloudfront:*", "route53:*",
"s3:ListAllMyBuckets", "support:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {"aws:RequestedRegion": ["ap-northeast-2", "us-east-1"]}
}
}
// 2. Block use of the root user (except emergencies)
{
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringLike": {"aws:PrincipalArn": "arn:aws:iam::*:root"}
}
}
// 3. Prohibit disabling CloudTrail
{
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"cloudtrail:UpdateTrail"
],
"Resource": "*"
}⚠️ Pitfall: In SCP example 1, excluding global services (IAM, CloudFront, Route 53) via
NotActionis the key. If you don't exclude them, that account can't even create IAM resources and becomes inoperable. In exam options, "region restriction without excluding global services" is a trap.
# List all accounts in the organization
aws organizations list-accounts --output table
# Accounts within a specific OU
aws organizations list-accounts-for-parent --parent-id ou-xxxx-yyyyyyyy
# SCP policy attachment status
aws organizations list-policies-for-target \
--target-id ou-xxxx-yyyyyyyy \
--filter SERVICE_CONTROL_POLICY
# Automatically create a new account
aws organizations create-account \
--email new-team@example.com \
--account-name "TeamA-Dev"
# Asynchronous: returns CreateAccountRequestId → poll with describe-create-account-statusNew account creation is asynchronous and usually takes 5-10 minutes. Meanwhile, Control Tower's Account Factory applies the baseline.
Remember today's three pictures. First, multi-account is the standard — blast radius isolation, quota separation, and compliance requirements are its justification. Second, Organizations + Control Tower is the foundation — standard OU structure + landing zone + guardrails. Third, IAM Identity Center is the definitive answer for authentication/authorization, and cross-account resource access is solved by three patterns: STS AssumeRole + resource policies + RAM.
The next post wraps up Week 1: we'll comprehensively review the first week's material through 10 scenario questions.