AWS Organizations
AWS Organizations lets you manage many AWS accounts as one hierarchy: organizational units, consolidated billing, Service Control Policies, centralised security & logging. The modern pattern is “one account per workload + env” with SCPs enforcing global guardrails.
OUs, SCPs, consolidated billing, security
EXAMPLE
// 1) Why multi-account?
// • Blast-radius isolation — dev breakage can't reach prod
// • Compliance — separate sensitive workloads from general purpose
// • Cost attribution — one account = one bill line item
// • Quotas — each account has its own service quotas
// • Different IAM trust models per workload
// Modern rule of thumb: per workload x env (dev / staging / prod / sandbox).
// 2) Organization structure
//
// Management account (org root)
// └── OU: Security
// ├── log-archive
// └── audit
// └── OU: Workloads
// ├── OU: Production
// │ ├── app-A-prod
// │ └── app-B-prod
// ├── OU: Non-production
// │ ├── app-A-staging
// │ ├── app-A-dev
// │ └── shared-services
// └── OU: Sandboxes
// └── eng-sandboxes
//
// AWS Control Tower can scaffold this with one click; or use Account Factory for Terraform.
// 3) Create an organisation (one-time, from the management account)
awscli> aws organizations create-organization --feature-set ALL
// 4) Create OUs + accounts
awscli> aws organizations create-organizational-unit \\
--parent-id r-abc1 --name 'Production'
awscli> aws organizations create-account \\
--email aws-prod-app-a@example.com \\
--account-name 'app-a-prod' \\
--role-name 'OrganizationAccountAccessRole'
# Returns CreateAccountStatus; poll until status SUCCEEDED.
// 5) Service Control Policies (SCPs)
// SCPs limit what IAM identities CAN do, even with admin permissions.
// They are GUARDRAILS — they don't grant permissions, only deny.
// Example: deny non-approved regions across the whole org
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"DenyNonApprovedRegions",
"Effect":"Deny",
"Action":"*",
"Resource":"*",
"Condition":{
"StringNotEquals":{
"aws:RequestedRegion":["ap-southeast-2","us-east-1"]
},
"ArnNotLike":{
"aws:PrincipalARN":["arn:aws:iam::*:role/aws-reserved/*"]
}
}
}
]
}
// Attach to root, OUs, or specific accounts
awscli> aws organizations attach-policy --policy-id p-abc --target-id ou-123
// 6) Useful SCP patterns
// • Region allowlist (above)
// • Deny root user actions in member accounts
// • Deny disabling CloudTrail / Config
// • Deny leaving the organization
// • Deny modifying log buckets in the log-archive account
// • Deny launching instance types outside an allowlist
// • Deny use of access keys older than X days
// 7) Consolidated billing
// • One bill across all accounts
// • Volume discounts apply across the entire org (S3, EC2, etc.)
// • Reserved Instances + Savings Plans share across the org
// • Use AWS Cost Explorer with linked-account filters for attribution
// • Tag every resource with CostCenter / Owner / Project — mandate via Tag Policies
// 8) Identity and access
// Best practice: IAM Identity Center (formerly AWS SSO) federates ONE IdP login (Okta, Entra, Google)
// to multiple accounts + roles. Users assume short-lived roles via SSO.
//
// Permission Sets define what each role can do per account.
// No long-lived IAM users in member accounts.
// 9) Centralised logging — the security OU pattern
// • log-archive account holds aggregated CloudTrail + Config logs
// • audit account hosts security tools (GuardDuty, Security Hub, Detective)
// • Member accounts forward logs cross-account to log-archive
// • Bucket policies pin write-only access; ops teams have read access only via audit account roles
// 10) Cross-account access — short-lived AssumeRole
// Member account creates a role with:
// Trust policy: { Service: 'ec2.amazonaws.com' } or { AWS: 'arn:aws:iam::management:role/admin' }
// Caller calls sts:AssumeRole, gets 1-hour credentials, then uses them.
awscli> aws sts assume-role \\
--role-arn 'arn:aws:iam::111122223333:role/OrganizationAccountAccessRole' \\
--role-session-name 'mara-debug'
// 11) Tag Policies — enforce tagging across the org
{
"tags": {
"CostCenter": { "tag_key": { "@@assign": "CostCenter" }, "enforced_for": { "@@assign": ["ec2:instance","s3:bucket"] } },
"Environment": { "tag_key": { "@@assign": "Environment" }, "tag_value": { "@@assign": ["dev","staging","prod"] } }
}
}
// 12) Backup, Resource Access Manager, others
// • AWS Backup — central backups across accounts
// • Resource Access Manager (RAM) — share resources (VPC subnets, prefix lists) across accounts
// • CloudFormation StackSets — deploy stacks to many accounts at once
// • AWS Config Aggregator — central view of compliance status
// 13) Account close + delete
// • Members can be removed from the org via 'leave-organization'
// • Closed accounts retain billing for 90 days then are permanently deleted
// • Plan for tear-down — delete IaC stacks, drain data, then close
// 14) Spending limits + budgets
// • AWS Budgets — alerts at thresholds; can trigger Lambda to disable IAM users
// • Cost Anomaly Detection — ML-based spending alerts
// • SCPs DON'T enforce cost; they enforce permissions. Use budgets + alerts.
// 15) Common bugs
// • Management account hosting workloads → blast radius; use it ONLY for org admin
// • SCP too aggressive → can lock OUT legitimate Service-linked-roles; test before applying to prod
// • Forgetting that SCPs deny — they NEVER grant; identity policies still required
// • Org email collisions — each account needs a unique address (use plus-addressing like aws+app-a-prod@)
// • Not turning on CloudTrail at the org level → blind spots
// • Multiple identity providers per account → drift; centralise on IAM Identity Center
// • SCP changes propagate within minutes — but IAM evaluation caching may delay; test
// • Closing accounts before migrating data — data lost permanently
Why it matters
AWS Organizations is the substrate for multi-account architecture: per-workload, per-env accounts inside OUs, with SCPs as global guardrails (region allowlist, prohibit root, lock CloudTrail). Use IAM Identity Center for SSO across accounts, centralise CloudTrail + Config in a log-archive account, and enforce tagging via Tag Policies for cost attribution.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…