EthicsComputerCourses
Join training +91 90532 10052

AWS Organizations, Multi-Account Setup & SCPs

AWS · Lesson 10 of 42 Beginner 8 min read Updated

A single AWS account works well while you learn. In a company it soon becomes a problem: a developer testing a script can delete a production table, one team's experiment eats the whole budget, and nobody can tell which bill belongs to which project. The modern answer is many small accounts, managed together with AWS Organizations.

In this lesson you will learn why companies use several accounts, how to arrange them in organisational units, how service control policies set hard limits, and where AWS Control Tower and IAM Identity Center fit.

Why one account is not enough

An AWS account is the strongest boundary AWS offers. Resources in one account cannot see or touch resources in another unless you deliberately allow it. Using separate accounts gives you:

  • Smaller blast radius: a mistake or a leaked credential in the dev account cannot delete production data.
  • Clear bills: each account's costs appear separately, so the finance team in Pune knows what the exam app costs compared with the website.
  • Separate limits: service quotas, such as the number of Lambda functions running at once, are per account, so one busy project does not starve another.
  • Simpler permissions: "developers are admins in dev, read-only in production" is easy when dev and production are different accounts.

AWS Organizations ties the accounts together. One account becomes the management account: it creates the organisation, pays the combined bill (consolidated billing) and manages policies. Every other account is a member account.

Organisational units and a typical layout

An organisational unit (OU) is a folder for accounts. Policies attached to an OU apply to every account inside it, including accounts in OUs nested below it (up to five levels deep). AWS's multi-account guidance suggests a layout like this for a small company, here an online coaching business in Jaipur:

Text
Root
├── Security OU
│   ├── log-archive      (CloudTrail and Config logs, locked down)
│   └── security-tools   (GuardDuty, Security Hub administrator)
├── Workloads OU
│   ├── Prod OU
│   │   └── coaching-prod
│   └── NonProd OU
│       └── coaching-dev
├── Sandbox OU
│   └── sandbox-aarav    (free experiments, strict budget)
└── Suspended OU          (accounts waiting to be closed)

Two rules matter most. First, run no workloads in the management account: it is the most powerful account and SCPs do not restrict it. Second, group accounts by how they should be governed (production, non-production, sandbox), not by team names, because teams change more often than rules.

Creating the organisation and a first OU takes a few commands, run with management account credentials. Organizations is a global service, and the root ID comes from list-roots:

Terminal
aws organizations create-organization --feature-set ALL \
  --query "Organization.{Id: Id, FeatureSet: FeatureSet}"

aws organizations list-roots --query "Roots[0].Id" --output text

aws organizations create-organizational-unit --parent-id r-a1b2 \
  --name Workloads --query "OrganizationalUnit.Id" --output text
Output
{
    "Id": "o-a1b2c3d4e5",
    "FeatureSet": "ALL"
}
r-a1b2
ou-a1b2-5e6f7g8h

--feature-set ALL is important. An organisation with only consolidated billing cannot use SCPs or the other policy types.

Creating accounts

New member accounts can be created from the management account. Each needs its own unique email address; a mail alias such as aws-coaching-prod@example.in on a shared team mailbox works well:

Terminal
aws organizations create-account --email aws-coaching-dev@example.in \
  --account-name coaching-dev \
  --query "CreateAccountStatus.{Request: Id, State: State}"

aws organizations list-accounts \
  --query "Accounts[].[Name, Id, State]" --output text
Output
{
    "Request": "car-a1b2c3d4e5f67890a1b2c3d4e5f67890",
    "State": "IN_PROGRESS"
}
jaipur-coaching-mgmt	111122223333	ACTIVE
coaching-dev	444455556666	ACTIVE

Account creation runs in the background, so the first command returns a request ID; describe-create-account-status tells you when it finishes. Organizations also creates a role named OrganizationAccountAccessRole in the new account, which administrators in the management account can assume. In practice you will give people access through IAM Identity Center permission sets instead, as shown in IAM Roles, Identity Center & Least Privilege.

Service control policies

A service control policy (SCP) sets the maximum permissions for IAM users and roles in member accounts. It never grants anything by itself: a user still needs an IAM policy that allows the action. Think of it as the school rule that overrides any permission a class teacher gives. If the SCP does not allow an action, nobody in that account can do it, not even an administrator or the account's root user.

Important facts:

  • SCPs apply to member accounts only, never to the management account.
  • Service-linked roles that AWS services use are not affected.
  • When you enable SCPs, AWS attaches a policy called FullAWSAccess everywhere. Leave it in place and add deny statements beside it. Removing it without a replacement blocks every action.
  • An account gets only what is allowed at every level above it: root, each parent OU and the account itself.

This SCP stops anyone in member accounts from leaving the organisation or switching off the audit trail and threat detection:

JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "StayInOrganization",
      "Effect": "Deny",
      "Action": "organizations:LeaveOrganization",
      "Resource": "*"
    },
    {
      "Sid": "ProtectAuditAndDetection",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:StopLogging",
        "cloudtrail:DeleteTrail",
        "guardduty:DeleteDetector",
        "guardduty:DisassociateFromAdministratorAccount"
      ],
      "Resource": "*"
    }
  ]
}

Save it as guardrails.json, create it and attach it to the Workloads OU:

Terminal
aws organizations create-policy --name core-guardrails \
  --type SERVICE_CONTROL_POLICY --description "Protect audit and membership" \
  --content file://guardrails.json \
  --query "Policy.PolicySummary.Id" --output text

aws organizations attach-policy --policy-id p-examplepol1 \
  --target-id ou-a1b2-5e6f7g8h
Output
p-examplepol1

attach-policy prints nothing on success. AWS strongly recommends testing a new SCP on a test OU with one or two accounts before attaching it to the root, because a wrong deny can lock everyone out of a service.

Other policy types and Control Tower

Organizations has more policy types for different jobs:

Policy typeWhat it controls
Service control policyMaximum permissions of users and roles in member accounts
Resource control policyMaximum permissions on resources (for example S3 buckets, KMS keys, SQS queues), even when someone outside the organisation is the caller
Tag policyWhich tag keys and values are allowed, such as cost-centre
Backup policyOrganisation-wide AWS Backup plans
Declarative policyFixed service settings, such as blocking public sharing of AMIs

Building all of this by hand is a lot of work. AWS Control Tower sets up a landing zone for you: an organisation with a Security OU, a log archive account, an audit account, IAM Identity Center, and a library of controls. Controls are preventive (usually SCPs), detective (usually AWS Config rules) or proactive (CloudFormation hooks that check resources before they are created). Its Account Factory creates new accounts that already follow your rules. Many companies start with Control Tower and add custom SCPs later.

Common mistakes

  • Running applications in the management account, where SCPs cannot protect them.
  • Detaching FullAWSAccess without a replacement allow policy, which blocks every action in the affected accounts.
  • Attaching an untested SCP to the root and breaking every account at once.
  • Expecting an SCP to grant access. SCPs only limit; IAM policies grant.
  • Sharing one email inbox per person for account root emails. Use team aliases so access survives when someone leaves.

Key points

  • Separate AWS accounts limit the blast radius of mistakes, separate bills and quotas, and simplify permissions.
  • AWS Organizations has one management account, member accounts and organisational units; keep workloads out of the management account.
  • SCPs set maximum permissions for member accounts and never grant access; keep FullAWSAccess and add deny statements.
  • SCPs do not affect the management account or service-linked roles; test them on a small OU first.
  • Resource control policies, tag, backup and declarative policies cover other governance needs.
  • AWS Control Tower builds a landing zone with log archive and audit accounts, controls and Account Factory.

Exercise

Meera manages AWS for a hospital chain in Kochi. Write an SCP for the Sandbox OU that (1) denies creating NAT gateways and (2) denies launching any EC2 instance type that is not t4g.micro or t4g.small. Hint: the condition key for the instance type is ec2:InstanceType on the instance resource.

Show solution
JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "NoNatInSandbox",
      "Effect": "Deny",
      "Action": "ec2:CreateNatGateway",
      "Resource": "*"
    },
    {
      "Sid": "OnlySmallInstances",
      "Effect": "Deny",
      "Action": "ec2:RunInstances",
      "Resource": "arn:aws:ec2:*:*:instance/*",
      "Condition": {
        "StringNotEquals": {
          "ec2:InstanceType": ["t4g.micro", "t4g.small"]
        }
      }
    }
  ]
}

Both statements are denies, so they work alongside the default FullAWSAccess policy. The second statement targets only the instance resource, because RunInstances also touches volumes, network interfaces and images that have no instance type.

Quick Quiz

1. What does a service control policy do?

2. Which account is never restricted by SCPs?

3. An account sits in the Prod OU under the root. Which SCPs decide its maximum permissions?

4. Which service builds a ready-made landing zone with log archive and audit accounts?

Learn AWS with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call