Multi-Account Guardrails with AWS SCPs

Enforce enterprise security boundaries across AWS accounts using SCPs.

Introduction

30 Second Summary

Imagine managing a company where different teams each have their own AWS account. Without centralized guardrails, any team member could accidentally deploy resources in a non-compliant region or disable critical audit logging.

In this project, you will build a fully governed multi-account AWS environment using AWS Organizations and Service Control Policies. You will deploy security guardrails that even root users cannot bypass.

What You'll Build

You will log in as the root user of a member account, attempt to disable CloudTrail logging, and watch your SCP block the action in real time, proving that organizational guardrails override even the most powerful credentials.

By the end of this project, you'll have:

  • A live AWS Organization with three accounts sorted into Production and Development organizational units, each governed by different security boundaries.
  • Three production-grade SCPs that lock member accounts to approved regions, prevent anyone from leaving the organization, and make CloudTrail untouchable.
  • A real-time demonstration where you log in as a member account's root user, attempt to stop audit logging, and watch the guardrail deny the action.
  • Secret Mission: Write a conditional SCP that restricts EC2 instance launches to an approved list of instance types.

Are there any prerequisites?

You need an existing AWS account. This becomes your management account. You also need 2 unique email addresses for creating member accounts.

Gmail aliases work perfectly for this. For example, you+dev@gmail.com and you+prod@gmail.com both route to your main inbox.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters that even a root user in a member account cannot escape your security controls.

Create Your AWS Organization and Enable SCPs

Right now, your AWS account is a standalone island. Any user with the right permissions can do anything, anywhere, with no central authority to override them.

To enforce organization-wide security boundaries, you need a governance layer that sits above individual accounts. AWS Organizations provides that layer, and Service Control Policies (SCPs) are the mechanism that lets you set hard limits on what member accounts can do. In this step, you'll create your Organization and enable SCPs.

In this step, get ready to:
  • Create your AWS Organization with all features enabled.
  • Enable Service Control Policies as a policy type.
  • Verify your organization is active and SCPs are ready to use.
Create your AWS Organization

An AWS Organization is the top-level container that groups multiple AWS accounts under centralized management. Creating one designates your current account as the management account.

  • In the AWS Management Console, type Organizations into the search bar at the top and select AWS Organizations from the results.
  • On the introduction page, click Create an organization.
  • In the confirmation dialog box, click Create an organization again.

The AWS accounts page appears. Your management account is listed under the Root organizational unit.

What just happened?

By default, the organization is created with all features enabled. This means SCPs are available as a policy type. Your current account automatically became the management account, which is the only account that can create and attach SCPs.

AWS may send a verification email to your management account's email address. Verify it within 24 hours. You can continue without it for now, but you'll need a verified email to invite existing accounts later.

Already have an Organization?

If your account is already part of an Organization, you'll see your existing structure instead of the introduction page. Confirm it was created with all features enabled by checking the Organization settings. If it only has consolidated billing, you'll need to enable all features first.

Enable Service Control Policies

Policy types are not enabled by default. You need to explicitly turn on the SCP policy type before you can create or attach any guardrails.

  • In the left navigation pane of the Organizations console, click Policies.
  • Click Service control policies.
  • Click Enable service control policies.

A green banner appears confirming that you can now create SCPs in your organization.

What is the FullAWSAccess policy?

When you enable SCPs, AWS automatically attaches a default policy called FullAWSAccess to every root, OU, and account. This policy allows all services and actions.

SCPs follow a deny-by-default evaluation model. Any permission not explicitly allowed is denied. The FullAWSAccess policy satisfies the "allow" requirement at every level, which is why adding Deny statements on top of it works as a guardrail strategy.

Verify your organization is active

Before you move on, confirm that everything is set up correctly. What do you expect to see on the Service control policies page now that SCPs are enabled?

  • On the Service control policies page, confirm you see the FullAWSAccess policy listed. This is the default SCP automatically attached to Root.
  • In the left navigation, click AWS accounts. Confirm your management account appears under Root.

You should see your management account listed as the only account in the organization, nested directly under Root. The Service control policies page shows the FullAWSAccess policy with an "AWS managed" tag.

Don't see the Enable button?

If the Enable service control policies button is missing, SCPs may already be enabled. Look for a list of existing policies instead. If you see the FullAWSAccess policy listed, you're all set.

If you see a message about consolidated billing features only, your Organization was not created with all features enabled. You'll need to enable all features first from the Organization settings page.

Help me troubleshoot my AWS Organizations setup.

Your governance layer is in place. Next up, you'll build the OU structure and create member accounts to test your policies against.

Build Your OU Structure and Create Member Accounts

Your Organization is live and SCPs are enabled. Next, you need a structure that separates accounts by purpose so you can apply different guardrails to different teams.

Right now your Organization is a flat list containing only the management account. A flat structure gives you no way to apply different security rules to different environments. Organizational units (OUs) solve this by grouping accounts so policies can target an entire group at once.

In this step, get ready to:
  • Create a Production OU and a Development OU under Root.
  • Create two member accounts and wait for them to reach Active status.
  • Move each account into its corresponding OU.
Create the Production and Development OUs

OUs are containers that sit between Root and your accounts. Any SCP you attach to an OU automatically applies to every account inside it.

  • In the AWS Organizations console, navigate to the AWS accounts page.
  • Select the checkbox next to the Root container.
  • Choose the Actions dropdown, then under Organizational unit, choose Create new.
  • For Organizational unit name, enter Production.
  • Choose Create organizational unit.

You should see the Production OU appear under Root in the console.

  • Select the checkbox next to the Root container again.
  • Choose Actions > Organizational unit > Create new.
  • For Organizational unit name, enter Development.
  • Choose Create organizational unit.

Both OUs now appear under Root in the organization tree.

What is an organizational unit?

An OU is a logical container inside your Organization. Think of it like a folder for accounts. Any policy you attach to an OU is inherited by every account inside it.

By separating Production from Development, you can later apply stricter guardrails to production workloads while giving developers more flexibility.

Create two member accounts

Member accounts are the AWS accounts your teams actually work in. You need two unique email addresses for these accounts. Gmail aliases work perfectly for this.

Gmail aliases for member accounts

Gmail treats you+anything@gmail.com the same as you@gmail.com. You can use aliases like you+prod@gmail.com and you+dev@gmail.com to create unique addresses without needing separate mailboxes.

  • On the AWS accounts page, choose Add an AWS account.
  • Choose Create an AWS account (selected by default).
  • For AWS account name, enter Prod-Account.
  • For Email address of the account's root user, enter your production email alias (for example, yourname+prod@gmail.com).
  • Leave the IAM role name field blank to use the default OrganizationAccountAccessRole.
  • Choose Create AWS account.

Account creation is asynchronous. You may need to wait a short while and refresh the page before the new account appears.

  • Once Prod-Account appears in the list, repeat the process to create the second account.
  • Choose Add an AWS account again.
  • For AWS account name, enter Dev-Account.
  • For Email address of the account's root user, enter your development email alias (for example, yourname+dev@gmail.com).
  • Leave IAM role name blank.
  • Choose Create AWS account.
  • Wait for both accounts to show Active status on the AWS accounts page. Refresh the page periodically until both display Active.

Account stuck on 'In progress'?

Account creation can take a few minutes. If the status does not change to Active after five minutes, refresh the page. If it remains stuck, check that the email address you used is not already associated with another AWS account.

help me troubleshoot why my member account creation is stuck

Move accounts into their OUs

Both accounts currently sit directly under Root. You need to move each one into its designated OU so that OU-level SCPs apply to the correct accounts.

  • On the AWS accounts page, select the checkbox next to Prod-Account (not its name).
  • Choose Actions, then under AWS account, choose Move.
  • On the Move page, select the radio button next to Production, then choose Move AWS account.

Prod-Account is now inside the Production OU.

  • Back on the AWS accounts page, select the checkbox next to Dev-Account.
  • Choose Actions > AWS account > Move.
  • Select the radio button next to Development, then choose Move AWS account.

Before you verify, predict what the organization tree should look like. What do you expect to see under Root, and which account should appear under each OU?

  • On the AWS accounts page, expand both the Production and Development OUs by choosing the triangle icon next to each one.

You should see: Root > Production OU (containing Prod-Account) and Root > Development OU (containing Dev-Account). Your management account remains directly under Root.

Account not appearing under the OU?

Make sure you selected the checkbox next to the account (not its name) before choosing Actions. Clicking the account name opens its details page instead of selecting it for an action.

If you accidentally moved an account to the wrong OU, select its checkbox again, choose Actions > AWS account > Move, and pick the correct OU.

help me fix my OU account placement in AWS Organizations

Your Organization now has a clean hierarchy with purpose-specific OUs. Next up, you will author your first SCP and attach it to Root to prevent any member account from leaving the organization.

Author and Attach the DenyLeaveOrganization SCP

Your Organization has a clean structure with accounts grouped into purpose-specific OUs. But there is a critical vulnerability right now.

Any member account can call organizations:LeaveOrganization and detach itself from your governance entirely. The moment an account leaves, every guardrail you build disappears for that account. Your first SCP closes this gap by denying that action across the entire Organization.

In this step, get ready to:
  • Write an SCP that blocks member accounts from leaving the Organization.
  • Attach the SCP to Root so it applies to every member account.
  • Verify both policies appear on Root's attached policy list.
Create the DenyLeaveOrganization policy

SCPs are JSON policies that set permission boundaries for every account beneath the node they are attached to. You will author a short Deny policy that targets a single action.

  • In the AWS Organizations console, click Policies in the left navigation panel.
  • Click Service control policies.
  • Click Create policy.
  • In the Policy name field, enter DenyLeaveOrganization.
  • Delete any placeholder JSON in the editor on the right, then paste the following policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "organizations:LeaveOrganization",
      "Resource": "*"
    }
  ]
}

What does this policy do?

This policy has a single statement with three key parts:

  • "Effect": "Deny" makes this a restrictive rule. It blocks rather than allows.
  • "Action": "organizations:LeaveOrganization" targets the specific API call an account would use to remove itself from the Organization.
  • "Resource": "*" applies the denial to all resources, meaning no exceptions.

Because SCPs follow a deny-by-default evaluation model, this Deny statement overrides any Allow that might exist in the account's IAM policies.

  • Click Create policy at the bottom of the page.

You should see a green success banner confirming the policy was created. The policy now appears in your Service control policies list.

Don't see a success banner?

  • Make sure you set Version to 2012-10-17 exactly. This is the only valid policy version string.
  • Check for trailing commas or missing quotation marks in the JSON. The editor highlights syntax errors in red.
  • Confirm you are signed into the management account. Only the management account can create SCPs.

Still stuck? Help me troubleshoot my SCP creation error in AWS Organizations.

Attach the SCP to Root

A policy that exists but is not attached to any target does nothing. Attaching to Root means the policy applies to every OU and account beneath it.

  • Click the DenyLeaveOrganization policy name to open its detail page.
  • Click the Targets tab.
  • Click Attach.
  • Select Root from the list of available targets.
  • Click Attach policy.

You should see Root listed under the Targets tab, confirming the attachment.

Why attach to Root instead of each OU?

SCP inheritance flows downward. A Deny statement attached at Root is automatically inherited by every OU and every account in the Organization.

Attaching to Root means you only manage one attachment point. If you later create new OUs or accounts, they are automatically covered without extra work.

Verify both policies are attached to Root

Before you check, think about what you expect to see. How many policies should be attached to Root right now, and what are their names?

  • In the left navigation, click AWS accounts.
  • Click Root at the top of the Organization tree.
  • Click the Policies tab on the Root detail page.

You should see two Service control policies listed: FullAWSAccess and DenyLeaveOrganization. Together, these mean every member account has full AWS access except the ability to leave the Organization.

How do these two policies work together?

The FullAWSAccess policy provides the broad Allow that every account needs to function. Without it, SCPs would deny everything by default.

Your DenyLeaveOrganization policy adds an explicit Deny on top. In AWS policy evaluation, an explicit Deny always wins over any Allow. This is the recommended deny-list approach for SCPs.

Only see FullAWSAccess?

  • Return to Policies > Service control policies and confirm DenyLeaveOrganization appears in the policy list. If it does, open it and check the Targets tab to confirm Root is listed.
  • If Root is not listed as a target, click Attach and select Root again.

Need more help? Help me figure out why my DenyLeaveOrganization SCP is not showing up on Root.

Your first guardrail is live. No member account can leave the Organization now, which means every future SCP you create will stay enforced. Next up, you will deploy a region lockdown SCP and discover a critical gotcha about how SCPs interact with the management account.

Deploy the Region Lockdown SCP

Your organization now prevents member accounts from leaving. The next security risk to address is unauthorized region usage.

When teams deploy resources in unapproved AWS regions, it creates data residency violations and makes security monitoring harder to manage. In this step, you will deploy a Region Lockdown SCP that restricts all member accounts to only your approved regions.

In this step, get ready to:
  • Create the RegionLockdown SCP using a Deny + NotAction + Condition pattern.
  • Attach the SCP to Root and test it from the management account.
  • Test the SCP from a member account to confirm enforcement.
Create the RegionLockdown SCP

The Region Lockdown policy uses a pattern called Deny + NotAction + Condition. It denies all actions unless they target an approved region, while exempting global services that only operate from a single endpoint.

  • Return to the AWS Organizations console.
  • In the left navigation, select Policies, then select Service control policies.
  • Click Create policy.
  • Enter RegionLockdown as the policy name.
  • Delete any pre-filled JSON in the policy editor, then paste the following policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RegionLockdown",
      "Effect": "Deny",
      "NotAction": [
        "a4b:*", "acm:*", "aws-marketplace-management:*",
        "aws-marketplace:*", "aws-portal:*", "budgets:*",
        "ce:*", "chime:*", "cloudfront:*", "config:*",
        "cur:*", "directconnect:*", "ec2:DescribeRegions",
        "ec2:DescribeTransitGateways", "ec2:DescribeVpnGateways",
        "fms:*", "globalaccelerator:*", "health:*", "iam:*",
        "importexport:*", "kms:*", "mobileanalytics:*",
        "networkmanager:*", "organizations:*", "pricing:*",
        "route53:*", "route53domains:*", "s3:GetAccountPublic*",
        "s3:ListAllMyBuckets", "s3:PutAccountPublic*", "shield:*",
        "sts:*", "support:*", "trustedadvisor:*",
        "waf-regional:*", "waf:*", "wafv2:*", "wellarchitected:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": ["us-east-1", "us-west-2"]
        }
      }
    }
  ]
}

What does this policy do?

This policy denies any action made in a region other than us-east-1 or us-west-2. The aws:RequestedRegion condition key checks which region the API call targets.

The NotAction list exempts global services like IAM, CloudFront, Route 53, and STS. These services have a single endpoint in us-east-1. Without this exemption, they would be completely blocked.

  • Click Create policy to save it.

You should see the RegionLockdown policy appear in your list of service control policies.

Policy not saving?

Make sure your JSON is valid. A missing comma or bracket will prevent saving. Check that the opening { and closing } are balanced. The console editor highlights syntax errors in red.

help me fix my RegionLockdown SCP JSON syntax error

Attach the SCP and test from the management account

With the policy created, you need to attach it to Root so it applies to every member account in the organization.

  • Select the RegionLockdown policy from the list.
  • Choose the Targets tab.
  • Click Attach, then select Root as the target.
  • Click Attach policy.

The RegionLockdown SCP is now attached to Root alongside FullAWSAccess and DenyLeaveOrganization.

Time to test. You are currently signed into the management account. Before you try this, what do you think will happen when you attempt to use a regional service in a non-approved region like ap-southeast-1?

  • In the navigation bar at the top of the console, click the currently displayed Region name.
  • Select Asia Pacific (Singapore) ap-southeast-1 from the region list.
  • Navigate to the S3 console by typing S3 in the search bar and selecting it.
  • Observe whether you can view the S3 buckets page.

The page loads normally. You can see your S3 buckets without any restriction. The SCP did not block you.

Why did the SCP not block me?

SCPs do not affect the management account. They only restrict member accounts in the organization. This is the most common real-world misconception with SCPs.

If you tested from the management account and concluded "my SCP doesn't work," you would be wrong. The policy is working. It just does not apply to the account you are signed into right now.

Test from the Dev-Account to confirm enforcement

To prove the SCP is actually enforcing the region lockdown, you need to access a member account. When you created the Dev-Account through AWS Organizations, a role called OrganizationAccountAccessRole was automatically created in that account. You can switch to this role from the management account.

What is OrganizationAccountAccessRole?

When you create a member account through Organizations, AWS automatically creates an IAM role named OrganizationAccountAccessRole in the new account. This role grants full administrative permissions and is configured to trust the management account. It is subject to any SCPs that apply to the member account.

  • First, switch back to an approved region. In the navigation bar, click the Region name and select US East (N. Virginia) us-east-1.
  • You need the Dev-Account's account ID. Return to the AWS Organizations console, select AWS accounts in the left navigation, and note the 12-digit account ID next to Dev-Account.
  • In the upper-right corner of the console, click your account name or user name.
  • Select Switch role.
  • Enter the Dev-Account's 12-digit account ID in the Account field.
  • Enter OrganizationAccountAccessRole in the Role field.
  • Click Switch Role.

Can't see Switch role?

If you are signed into the console as the AWS account root user, you cannot use Switch Role. You need to sign in as an IAM user with administrator permissions instead. Create an IAM user with AdministratorAccess policy, sign in with that user, then retry.

help me access my member account from the management account

You are now operating inside the Dev-Account. The navigation bar in the upper-right shows the role name and account, confirming you switched successfully.

Now for the real test. What do you think will happen when you try to access S3 in ap-southeast-1 from this member account?

  • In the navigation bar, click the Region name and select Asia Pacific (Singapore) ap-southeast-1.
  • Navigate to the S3 console by typing S3 in the search bar and selecting it.
  • Try to click Create bucket.

You see an Access Denied error. The SCP is enforcing the region lockdown on member accounts, blocking you from creating resources in an unapproved region.

What just happened?

The same action that worked moments ago from the management account is now denied from the member account. This is the fundamental SCP behavior: SCPs restrict member accounts (including their root users) but never affect the management account.

This is why AWS best practice is to deploy no workloads in the management account. Keep it as a governance-only account. All real resources should live in member accounts where SCPs can protect them.

  • Switch back to the management account. Click the role display name in the upper-right corner and select Switch back.

Not seeing the Access Denied error?

Confirm you successfully switched to the Dev-Account role before changing regions. The navigation bar should show the role name, not your management account user name. If it still shows your management account identity, the switch did not complete.

Also confirm you selected ap-southeast-1 and not one of the approved regions (us-east-1 or us-west-2). Actions in approved regions will still work normally.

help me troubleshoot why my Region Lockdown SCP is not blocking actions in the member account

Your Region Lockdown SCP is live. Member accounts are physically unable to operate outside your two approved regions. Next up, you will deploy the ultimate test: an SCP that protects CloudTrail audit logging, and prove that even the root user of a member account cannot override it.

Deploy the CloudTrail Protection SCP and Prove Root Cannot Bypass It

In the previous step, you proved that SCPs enforce region lockdown on member accounts but not on the management account. Now it is time for the ultimate test of organizational guardrails.

CloudTrail is your audit log for every action across your AWS accounts. If someone disables it, you lose visibility into what happened and when. This SCP makes CloudTrail untouchable. You will prove it by logging in as the root user of a member account and watching the SCP block the action in real time.

In this step, get ready to:
  • Create the ProtectCloudTrail SCP that denies all dangerous CloudTrail actions.
  • Attach the SCP to Root so it applies to every member account.
  • Prove that even the root user of a member account cannot stop CloudTrail logging.
Create the ProtectCloudTrail SCP

This policy denies four critical CloudTrail actions on all trail resources. Once attached, no member account can delete a trail, stop logging, change event selectors, or update trail configuration.

  • In the AWS Organizations console, select Policies in the left navigation.
  • Select Service control policies.
  • Click Create policy.
  • In the Policy name field, enter ProtectCloudTrail.
  • Clear the default JSON in the left-side editor and paste the following policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "GRCLOUDTRAILENABLED",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:DeleteTrail",
        "cloudtrail:PutEventSelectors",
        "cloudtrail:StopLogging",
        "cloudtrail:UpdateTrail"
      ],
      "Resource": [
        "arn:aws:cloudtrail:*:*:trail/*"
      ]
    }
  ]
}
  • Click Create policy to save.

What does this policy do?

The four denied actions cover every way to tamper with CloudTrail. cloudtrail:DeleteTrail removes the trail entirely. cloudtrail:StopLogging suspends event recording. cloudtrail:PutEventSelectors can narrow which events are logged. cloudtrail:UpdateTrail can redirect logs to an attacker-controlled bucket.

The wildcard resource arn:aws:cloudtrail:*:*:trail/* means this applies to every trail in every region across every member account.

You should see ProtectCloudTrail appear in your list of service control policies.

Attach the SCP to Root and access the Dev-Account as root user

Attaching to Root means every account in the organization (except the management account) is now protected.

  • Click on the ProtectCloudTrail policy you just created.
  • Select the Targets tab.
  • Click Attach.
  • Select Root and click Attach policy.

The Targets tab should now show Root listed as an attached target. Your CloudTrail guardrail is live.

Why attach to Root instead of individual OUs?

Attaching to Root ensures the policy cascades to every OU and every account beneath it. If you attached only to the Development OU, someone could move an account to Production OU to escape the restriction. Attaching at Root makes the guardrail inescapable for all member accounts.

Now you need to access the Dev-Account as its root user to perform the bypass test. When a member account is created through Organizations, no root password is set. You need to use the password reset flow.

  • Open a new browser tab or incognito window.
  • Go to the AWS sign-in page and select Root user.
  • Enter the email address you used when creating the Dev-Account (e.g., you+dev@gmail.com).
  • Click Forgot password? to trigger the password reset flow.
  • Check your email for the reset link, set a new password, and sign in as the Dev-Account root user.

Gmail aliases route to your main inbox

If you used a + alias like you+dev@gmail.com, the password reset email arrives in your main Gmail inbox. No separate account needed.

Not receiving the password reset email?

Check your spam folder. AWS password reset emails sometimes land there. Also confirm you typed the exact email address you used when creating the member account in Step 2.

If the account still shows as initializing, wait a few minutes. Newly created accounts can take up to a few minutes to become fully active.

Still stuck? Help me access my member account root user via password reset.

Attempt to stop CloudTrail logging as the member account root user

You are now signed in as the root user of Dev-Account. This is the most powerful identity inside this account. If the SCP works, even this identity cannot touch CloudTrail.

  • In the Dev-Account console, use the search bar to navigate to CloudTrail.
  • Select Trails in the left navigation.
  • If no trail exists, click Create trail, name it test-trail, accept all defaults, and click Next through the wizard until it is created.

Why create a trail first?

You need an existing trail to attempt to stop or delete. Creating a trail is allowed because cloudtrail:CreateTrail is not blocked by your SCP. Only the destructive actions (delete, stop, update, change selectors) are denied.

Before you attempt the next action, predict what will happen. You are the root user of this account. Do you think you can stop CloudTrail logging?

  • Select your trail (test-trail or whichever trail exists).
  • Click Stop logging (or attempt to delete the trail by selecting it and choosing Delete).

The action is denied. You will see an error message indicating the request was blocked with an explicit deny in a service control policy. Even the root user of a member account cannot override an SCP.

What does this prove?

SCPs affect all member accounts, including their root users. The only account exempt from SCPs is the management account. This means your organizational guardrails are truly inescapable for anyone operating inside a member account.

In a real enterprise, this is how security teams guarantee audit integrity. No rogue administrator in any member account can destroy the evidence trail.

  • Sign out of the Dev-Account.
  • Switch back to your management account in the original browser tab.

Action succeeded instead of being denied?

Double-check that you are signed into the Dev-Account (a member account), not the management account. SCPs do not apply to the management account.

Verify the ProtectCloudTrail SCP is attached to Root. In the Organizations console under your management account, go to Policies > Service control policies > ProtectCloudTrail > Targets tab. Root should be listed.

Still not working? Help me troubleshoot why my CloudTrail protection SCP is not blocking actions.

Secret mission

Conditional SCP for Approved EC2 Instance Types

Real enterprises do not just lock regions. They also control cost and security by restricting which instance types teams can launch. Can you write a conditional SCP that denies EC2 instance launches unless the instance type is from an approved list?

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. AWS Organizations and SCPs are free, and member accounts with no running resources incur no charges. The only potential cost comes from test resources you created during verification (EC2 instances, S3 buckets, or CloudTrail trails).

Cost warning

If you launched EC2 instances, created S3 buckets, or set up CloudTrail trails during your testing, those resources may incur charges if left running. Delete them promptly if you are not using them.

Resources you used:

  • AWS Organization (free).
  • 2 member accounts: Prod-Account and Dev-Account (free if no resources running).
  • 4 SCPs: DenyLeaveOrganization, RegionLockdown, ProtectCloudTrail, DenyUnapprovedInstanceTypes (free).
  • 2 OUs: Production and Development (free).
  • Any test resources created during verification (EC2 instances, S3 buckets, CloudTrail trails).

Keep everything running

No action needed. Choose this if you want to continue experimenting with your Organization and SCPs.

  • The Organization, OUs, and SCPs cost nothing to maintain.
  • Member accounts with no running resources cost nothing.
  • Delete any test EC2 instances or S3 buckets you created during verification to avoid storage or compute charges.

Pause - I'll come back to this later

Delete test resources to stop any charges, but keep your Organization structure intact so you can return to it later.

  • Terminate any EC2 instances you launched during testing. In the EC2 console, select the instance, choose Instance state, then Terminate instance.
  • Delete any S3 buckets you created. In the S3 console, select the bucket, choose Empty, confirm, then choose Delete.
  • Delete any CloudTrail trails you created for testing. In the CloudTrail console, select the trail and choose Delete.
  • Your Organization, OUs, SCPs, and member accounts remain in place at no cost.

Delete - I don't want to use this again

Remove all project resources completely. Follow these steps in order because some resources depend on others being removed first.

Step 1: Delete test resources.

  • Terminate any EC2 instances you launched. In the EC2 console, select the instance, choose Instance state, then Terminate instance.
  • Delete any S3 buckets. In the S3 console, select the bucket, choose Empty, confirm, then choose Delete.
  • Delete any CloudTrail trails. In the CloudTrail console, select the trail and choose Delete.

Step 2: Detach and delete all custom SCPs.

  • In the AWS Organizations console, go to Policies then Service control policies.
  • Select DenyLeaveOrganization. Go to the Targets tab and detach it from Root. Then choose Delete and confirm by entering the policy name.
  • Repeat for RegionLockdown (detach from Root, then delete).
  • Repeat for ProtectCloudTrail (detach from Root, then delete).
  • Repeat for DenyUnapprovedInstanceTypes (detach from the Development OU, then delete).
  • Do not delete the FullAWSAccess policy. It is AWS-managed and cannot be deleted.

Step 3: Close member accounts.

  • In the AWS Organizations console, go to AWS accounts.
  • Select Prod-Account, then choose Close. Confirm by entering the account ID.
  • Select Dev-Account, then choose Close. Confirm by entering the account ID.
  • Closed accounts enter a 90-day suspended state before permanent deletion. This action is irreversible.

Step 4: Delete OUs.

  • Once the member accounts are removed from the OUs (closing moves them out), select the Production OU, choose Actions, then Delete.
  • Repeat for the Development OU.

Step 5: Delete the Organization.

  • In the AWS Organizations console, go to Settings.
  • Choose Delete organization and confirm by entering the organization ID.
  • Your management account becomes a standalone AWS account again.

Nice Work!

Nice Work!

You just built an enterprise-grade governance layer across a multi-account AWS environment. Your Organization now enforces security boundaries that no individual account can override.

Here's what you learned:

  • Built a live AWS Organization with a management account and two member accounts organized into purpose-specific Organizational Units.
  • Authored and deployed three production-grade Service Control Policies (DenyLeaveOrganization, RegionLockdown, and CloudTrailProtection) that enforce security guardrails across all member accounts.
  • Proved that even the root user of a member account cannot bypass organizational guardrails by attempting to stop CloudTrail logging and watching the SCP deny the action in real time.
  • Created a conditional SCP restricting EC2 instance types to an approved list at the OU level, proving selective policy application.

Ready to quiz yourself?