AWS Organizations and Multi-Account Strategy: The Right Structure for Growing Teams

April 13, 2026 — Nick Allevato

Most AWS environments start in a single account. It’s the path of least resistance — one bill, one IAM namespace, one set of limits. As teams grow, the problems accumulate: a developer’s misconfigured security group in a test environment exposing production data, S3 buckets with inconsistent policies across services, no budget isolation between teams, and audit logs that mix production events with development noise.

The fix is a multi-account structure. But designing it wrong creates a different set of problems: too many accounts that are hard to manage, or accounts without the governance guardrails that make them useful.

Here’s how to do it right.


Why separate accounts at all

AWS accounts are a hard security boundary. IAM policies within an account can always be misconfigured — a developer with admin access can create overly permissive policies, accidentally expose an S3 bucket, or modify production infrastructure when they intended to modify staging. Accounts prevent these mistakes from crossing environment boundaries entirely.

With a single account:

  • A compromised IAM credential has blast radius across all environments
  • No way to enforce “developers can only modify dev resources” at the infrastructure level
  • Cost attribution requires tagging discipline (which erodes over time)
  • Audit logs for SOC 2 or compliance purposes mix production and development events
  • AWS service quotas (Lambda concurrency, EC2 instance limits) are shared across all environments

With separate accounts per environment:

  • IAM credentials in dev accounts cannot affect production resources — enforced by AWS, not by policy text
  • Budget alerts and cost visibility per environment without tagging
  • Production CloudTrail is clean for compliance purposes
  • Quota exhaustion in dev doesn’t affect production

The foundational structure

For most SaaS companies and engineering teams, this structure works well:

Root (management account — billing only)
├── Security OU
│   └── Security Tooling account (GuardDuty master, Security Hub, CloudTrail aggregation)
├── Infrastructure OU
│   └── Shared Services account (ECR, VPN, transit gateway, shared DNS)
├── Workloads OU
│   ├── Production account(s)
│   ├── Staging account
│   └── Development account
└── Sandbox OU
    └── Individual developer sandbox accounts (optional)

Management account: Used exclusively for billing and AWS Organizations administration. No workloads. No IAM users for daily use. This account’s credentials should be tightly protected — it can close member accounts, modify SCPs, and access billing for the entire organization.

Security Tooling account: Centralizes security services. GuardDuty aggregates findings from all member accounts into this account. CloudTrail organization trail sends all events here. Security Hub consolidates. One place to look for security findings across the entire organization.

Shared Services account: Resources that multiple workload accounts need: ECR (container images), internal DNS zones, a transit gateway for VPC connectivity. Centralizing ECR means one image registry with one set of access policies, rather than managing ECR in every environment account.

Workload accounts: One per environment (production, staging, development). Sometimes one per service for larger organizations, but per-environment is the right starting point.


Service Control Policies: the guardrails that actually enforce things

SCPs are the governance layer of AWS Organizations. They define the maximum permissions any IAM principal in a member account can have — regardless of what the IAM policy in that account says.

SCPs don’t grant permissions. They restrict them. If the management account SCP denies an action, no IAM policy in the member account can allow it, including Administrator.

Useful SCPs for most organizations:

Deny leaving the organization:

{
  "Effect": "Deny",
  "Action": "organizations:LeaveOrganization",
  "Resource": "*"
}

Without this, a compromised account admin can remove the account from the organization, bypassing all other SCPs.

Deny disabling GuardDuty:

{
  "Effect": "Deny",
  "Action": [
    "guardduty:DeleteDetector",
    "guardduty:DisassociateFromMasterAccount",
    "guardduty:UpdateDetector"
  ],
  "Resource": "*",
  "Condition": {
    "ArnNotLike": {
      "aws:PrincipalArn": "arn:aws:iam::*:role/SecurityAdminRole"
    }
  }
}

Deny disabling CloudTrail:

{
  "Effect": "Deny",
  "Action": [
    "cloudtrail:DeleteTrail",
    "cloudtrail:StopLogging",
    "cloudtrail:UpdateTrail"
  ],
  "Resource": "*"
}

Restrict to approved regions (example — us-east-1 and us-west-2 only):

{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": ["us-east-1", "us-west-2"]
    }
  }
}

This prevents accidental resource creation in regions you don’t use, which both reduces cost exposure and simplifies compliance scope.

Require encryption for S3 objects:

{
  "Effect": "Deny",
  "Action": "s3:PutObject",
  "Resource": "*",
  "Condition": {
    "Null": {
      "s3:x-amz-server-side-encryption": "true"
    }
  }
}

Apply SCPs at the OU level, not the account level, so new accounts inherit the guardrails automatically.


IAM Identity Center: single sign-on for the whole organization

Without IAM Identity Center (formerly AWS SSO), each developer needs IAM users in each account — separate credentials, separate MFA, separate password rotation. For an organization with 5 accounts and 10 developers, that’s managing 50 sets of credentials.

IAM Identity Center provides:

  • Single login for all accounts in the organization
  • Permission sets (named bundles of IAM permissions) assigned to groups
  • Temporary credentials via SAML federation — no long-lived access keys
  • Integration with your existing IdP (Okta, Google Workspace, Azure AD, or the built-in directory)

The standard setup:

  1. Enable IAM Identity Center in the management account
  2. Connect your IdP (or use the built-in directory)
  3. Define permission sets: AdministratorAccess, DeveloperAccess, ReadOnlyAccess
  4. Assign groups to permission sets per account

A developer gets temporary credentials for the accounts they need, scoped to the permission set appropriate for that account. When they leave the company, you disable their IdP account — access to all AWS accounts is revoked automatically.


AWS Control Tower: the managed setup

AWS Control Tower automates the multi-account setup: creates the management structure, deploys a landing zone with opinionated account vending, configures CloudTrail organization trail, and sets up guardrails (which are SCPs + AWS Config rules).

Control Tower is worth using if:

  • You’re starting from scratch and want the structure done correctly without building it manually
  • Your organization is growing rapidly and you need account vending (new accounts on-demand)
  • You want AWS-maintained guardrails that update as new services are released

Control Tower is not worth using if:

  • You already have an existing Organizations structure you’d need to retrofit
  • You have specific customization requirements that conflict with Control Tower’s opinionated setup
  • You have a small, stable account count where the overhead isn’t justified

The common issue with Control Tower: it’s harder to customize than building Organizations directly. The guardrails update on AWS’s schedule, not yours, which can cause drift with your existing infrastructure.


Cross-account access patterns

With multiple accounts, resources in one account frequently need to access resources in another. The right pattern depends on what’s being accessed.

Cross-account IAM roles (the standard pattern):

Account A (workload) needs to read from ECR in the Shared Services account:

In the Shared Services account, create a role with a trust policy:

{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::WORKLOAD-ACCOUNT-ID:role/ECSTaskRole"
  },
  "Action": "sts:AssumeRole"
}

The workload account’s ECS task assumes this role to pull images. No long-lived credentials.

Resource-based policies (for S3, KMS, Secrets Manager):

These services support resource policies that grant cross-account access directly:

{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::WORKLOAD-ACCOUNT-ID:role/ECSTaskRole"
  },
  "Action": ["s3:GetObject"],
  "Resource": "arn:aws:s3:::shared-artifacts/*"
}

VPC sharing vs. peering vs. transit gateway:

For network connectivity between accounts:

  • VPC peering: Direct connection between two VPCs, in the same or different accounts. Simple, low cost, but doesn’t scale (N*(N-1)/2 peering connections for N VPCs).
  • Transit Gateway: Hub-and-spoke model. All VPCs connect to one transit gateway. Scales to hundreds of VPCs. Costs $0.05/hour per attachment + $0.02/GB processed.
  • VPC sharing (Resource Access Manager): Share subnets from one account to others. Resources in multiple accounts appear in the same VPC. Simpler than peering for same-region setups, but less isolation than separate VPCs.

For most organizations: transit gateway in the Shared Services account, VPC peering for simple two-account setups.


Cost management across accounts

AWS consolidated billing combines all member account costs into the management account bill. This means:

  • Reserved Instance and Savings Plans discounts apply across accounts — a Savings Plan purchased in any account applies to matching usage in all accounts
  • Volume discounts aggregate across the organization
  • Cost Explorer shows per-account breakdown

Enable Cost Explorer at the organization level and create budgets per account with SNS alerts. $0/month budget with alert at 80% of expected spend is a simple anomaly detection approach.

AWS Cost Anomaly Detection (free to enable, charges for alerts after 100 anomalies) automatically detects unusual spend patterns per service, per account, per cost category.


When to add accounts

A common mistake: creating an account for every team, every service, every environment combination. This creates operational overhead without proportional benefit.

Add an account when:

  • There’s a hard compliance requirement for environment isolation (SOC 2, HIPAA, PCI DSS typically require production isolation)
  • A team has admin-equivalent access needs that would create blast radius risk in a shared account
  • You need separate AWS service quotas (a video processing pipeline that hammers Lambda concurrency limits shouldn’t compete with the main application)
  • A department needs billing isolation with chargeback

Don’t add accounts:

  • For every microservice (use namespaces, tags, or VPCs within an account instead)
  • For every feature branch (ephemeral environments within the dev account)
  • Just to have more accounts

The right number of accounts for a 50-person engineering team is typically 5-10, not 50.


Getting started

If you’re still in a single account and considering the move to multi-account:

  1. Start with the management account and a production account — separate the most critical environment first
  2. Enable an organization trail in CloudTrail (captures all accounts’ events)
  3. Add IAM Identity Center with your existing IdP
  4. Apply foundational SCPs (deny leaving org, deny disabling GuardDuty/CloudTrail)
  5. Add workload accounts for staging and development
  6. Add the Security Tooling account and configure GuardDuty org-wide

This is a 2-3 week engagement for a team starting from scratch, or 1-2 weeks if you’re retrofitting an existing single-account environment.


Getting help

Multi-account architecture design is one of the engagements I do most often — the foundational structure affects everything that comes after, so getting it right the first time matters. Let’s talk if you’re planning the move.


Nick Allevato is an AWS Certified Solutions Architect Professional with 20 years of infrastructure experience. He runs Cold Smoke Consulting, an independent AWS consulting practice.