A customer I work with wanted to add a custom restriction to prevent all accounts from using AWS regions outside the US. They weren’t sure if they could add their own SCPs alongside Landing Zone’s managed SCPs, or if that would cause conflicts. After walking them through the process, we safely added a custom SCP that works perfectly with Landing Zone’s guardrails. In this post, I’ll walk through exactly how to add custom SCPs to your Landing Zone deployment.

The Problem

Your AWS Landing Zone deployment comes with default SCPs attached to Organizational Units (OUs). These control things like preventing account deletion and requiring CloudTrail. Now you need to add your own custom restrictions—maybe enforce a specific AWS region, prevent public S3 bucket creation, or deny EC2 instance types. You’re concerned about conflicting with Landing Zone’s SCPs and breaking guardrails.

The challenge is: Landing Zone manages its own SCPs via CloudFormation StackSets. If you modify them directly, you risk drift and losing your changes on the next Landing Zone update.

Why This Matters

AWS applies SCPs as a whitelist/blacklist. Multiple SCPs are AND’d together. If any SCP denies an action, the action is denied. This means you can safely add custom SCPs alongside Landing Zone’s managed ones—they’ll work together in defense-in-depth.

The Fix: Add Custom SCPs Alongside Landing Zone

Step 1: Create Your Custom SCP

First, define your custom SCP. Here’s an example that restricts usage to US regions only:

Create a file called deny-non-us-regions.json:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "NotAction": [
        "iam:*",
        "organizations:*",
        "account:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "us-east-1",
            "us-west-2",
            "us-east-2"
          ]
        }
      }
    }
  ]
}

This SCP denies all API calls outside the specified regions, with exceptions for global services like IAM and Organizations.

Step 2: Create the Policy in Organizations

Create the SCP in AWS Organizations:

aws organizations create-policy \
  --name DenyNonUSRegions \
  --description "Restrict all API calls to US regions" \
  --type SERVICE_CONTROL_POLICY \
  --content file://deny-non-us-regions.json \
  --region us-east-1

The command returns the policy ID, which you’ll need next.

Step 3: Attach the SCP to an OU

Attach the SCP to the OU where you want it to apply. For example, attach it to your “Development” OU:

# First, list your OUs to find the OU ID
aws organizations list-organizational-units-for-parent \
  --parent-id r-xxxx \
  --region us-east-1

# Then attach the SCP
aws organizations attach-policy \
  --policy-id p-xxxxxxxxxx \
  --target-id ou-xxxx-xxxxxxxx \
  --region us-east-1

The policy now applies to all accounts in that OU and its child OUs.

Step 4: Test the SCP

In one of the accounts under that OU, try to perform an action in a denied region:

# This should be denied
aws ec2 describe-instances \
  --region eu-west-1 \
  --region us-east-1

You should see an error like:

An error occurred (UnauthorizedOperation) when calling the DescribeInstances
operation: You are not authorized to perform this operation.
Encoded authorization failure message...

Try the same command in an allowed region (us-east-1) and it should work.

For Landing Zone Accelerator (LZA) Users

If you’re using LZA instead of the original Landing Zone, you can also add custom SCPs via the configuration files. This keeps everything version-controlled and deployed alongside your infrastructure:

Step 1: Add SCP to customizations-config.yaml

In your LZA configuration repo, edit customizations-config.yaml:

serviceControlPolicies:
  - name: DenyNonUSRegions
    description: Restrict all API calls to US regions
    type: SERVICE_CONTROL_POLICY
    strategy: DENY
    statements:
      - effect: Deny
        actions:
          - '*'
        excludedActions:
          - 'iam:*'
          - 'organizations:*'
          - 'account:*'
        resources:
          - '*'
        conditions:
          - condition: StringNotEquals
            key: aws:RequestedRegion
            value:
              - us-east-1
              - us-west-2
              - us-east-2
    targets:
      organizationalUnits:
        - Development
        - Staging

Step 2: Deploy the LZA Pipeline

Commit and push your changes:

git add customizations-config.yaml
git commit -m "Add custom SCP for US regions only"
git push origin main

The LZA pipeline automatically detects the change and deploys the SCP to the specified OUs.

Common Custom SCPs

Here are a few other useful SCPs you might want to add:

Deny Public S3 Buckets:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "s3:PutAccountPublicAccessBlock"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "s3:x-amz-acl": [
            "public-read",
            "public-read-write"
          ]
        }
      }
    }
  ]
}

Require MFA for Sensitive Actions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "iam:DeleteUser",
        "iam:DeleteRole"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}

Is This Safe?

Yes, adding custom SCPs alongside Landing Zone’s managed SCPs is completely safe. SCPs are evaluated as AND logic—if any policy denies an action, it’s denied. Your custom SCPs work in conjunction with Landing Zone’s guardrails, not against them.

Just remember:

  • Always test SCPs in a non-production OU first
  • SCPs apply immediately—there’s no deployment window
  • Root user and the management account are exempt (by design)

Key Takeaway

You can safely add custom SCPs to your Landing Zone deployment by creating them in Organizations and attaching them to OUs. For LZA users, define SCPs in customizations-config.yaml for version control. Custom SCPs work alongside Landing Zone’s guardrails in defense-in-depth.


Have questions or ran into a different Landing Zone issue? Connect with me on LinkedIn or X.