AWS CDK Landing Zone

Add an Account

Add a new AWS account to an existing OU in organization-structure.ts and deploy it through the landing zone.

When your organization needs a new AWS account (a new workload environment, a team sandbox, or a specialized service account), you add it to organization-structure.ts and deploy. The landing zone creates the account, moves it into the right OU, and automatically rolls out the account baseline (secure defaults, CloudTrail, and cost controls, plus CDK bootstrap for accounts in the Development and Production OUs) without any manual intervention. Because GuardDuty, Security Hub, Inspector, and Macie are configured org-wide from the security account, a new account is enrolled in whichever of those services you have enabled.

Steps

1. Choose an OU and a unique email address

Pick the OU the new account belongs to. The starter ships with DevelopmentOU and ProductionOU for workload accounts, but any OU in your structure works.

Choose an email address that has never been used for any AWS account globally. The aws+<alias>@<domain> plus-addressing pattern lets you generate unique addresses under a single domain:

aws+payments-prod@example.com

If you already manage multiple accounts under your domain, check your existing accounts first to confirm the address is free.

2. Add the account in organization-structure.ts

Open src/config/organization-structure.ts and add a new entry to the accounts map of the target OU. Each account key becomes the SSM parameter suffix and the TypeScript property name on orgVars, so keep it descriptive and PascalCase:

ProductionOU: {
  name: `${orgName}-workload-prod-ou`,
  accounts: {
    WorkloadAlphaAccount: {
      name: 'Workload Alpha',
      email: `aws+workload-alpha@${mailDomain}`,
    },
    // Add your new account here:
    PaymentsAccount: {
      name: 'Payments',
      email: 'aws+payments-prod@example.com',
    },
  },
},

The name field is the display name shown in the AWS Organizations console. The email is the root email address for the new account.

To attach account-specific SCPs at the same time, add a serviceControlPolicies array to the account entry. See Service Control Policies for the available SCPs and the 5-per-target limit.

3. Preview the change

Run a diff to confirm only the expected resources change before deploying:

pnpm run management:diff

You should see a new AWS::Organizations::Account resource and an SSM parameter (/organization/PaymentsAccountId) in the diff output for the OrganizationStack.

4. Deploy

pnpm run management:deploy

This deploys all three stacks in sequence. The organization stack runs first: it creates the account and publishes its ID to SSM. The landing-zone stacks follow and trigger the Phase 3 StackSets, which roll out the baseline to the new account automatically.

For CI/CD, push to main and let the generated GitHub Actions workflow handle the deployment. See GitHub Actions Deployment for how that pipeline works.

5. Verify

After the deploy completes, confirm the account exists in AWS Organizations:

aws organizations list-accounts --query 'Accounts[?Name==`Payments`]'

Then confirm the SSM parameter was published:

aws ssm get-parameter --name /organization/PaymentsAccountId --query Parameter.Value

The baseline StackSets run asynchronously after the account is created. Check the StackSet instance status in the CloudFormation console (under StackSets) to confirm the instance for the new account reached CURRENT.

What happens on deploy

OrganizationStack calls the AWS Organizations API to create the account and move it into the target OU. It then publishes the new account ID to SSM under /organization/PaymentsAccountId and updates /organization/AllAccountIds.

The SetAlternateContactConstruct and UnsubscribeMarketingMailsConstruct in the same stack detect the new account email and run their automation against the new account: applying your configured billing, security, and operations contacts, and opting the account out of AWS marketing email.

LandingZoneAccountProvisioningStack (Phase 3) reads the updated OU membership from AWS Organizations and deploys service-managed StackSet instances to the new account. Because the Phase 3 StackSets target OUs rather than explicit account lists, new accounts that join a targeted OU receive their stack instances automatically without any changes to the stack code. Quota increase requests are submitted asynchronously; they may take up to 24 hours to be approved by AWS.