AWS CDK Landing Zone

Stacks

The CDK Landing Zone deployment stacks, LandingZoneOrganizationStack, LandingZoneFoundationStack, and LandingZoneAccountProvisioningStack, and the two account phases they deploy in.

The landing zone deploys through three CDK stacks in a fixed order, split across two AWS accounts. The organization phase deploys one stack to your management account. The landing-zone phase deploys the other two from a dedicated landing zone account, which acts as the CloudFormation StackSets delegated administrator. Keeping the StackSet rollout off the management account is the main structural change: the management account owns the organization, and the landing zone account does the provisioning.

Mermaid diagram loading.Management account Landing zone account

Each stack depends on outputs from LandingZoneOrganizationStack, which is why the first deployment runs in two steps: the organization must exist, and the landing zone account must be registered as the StackSets delegated administrator, before the landing-zone stacks can target the organization's accounts.

Organization phase: LandingZoneOrganizationStack

Deploys to the management account. It runs first because every later stack consumes the organization identifiers it publishes, and because it sets up everything the landing zone account needs to take over provisioning.

What it createsDetails
AWS OrganizationFeature set ALL. Enables the organization policy types (SCP, resource control, tag, backup, Inspector, and Security Hub by default)
Trusted service accessEnables trusted access for the AWS services listed in trusted-access.ts so org-wide features and delegated administration can operate
Organizational UnitsAs defined in organization-structure.ts
AWS accountsCreated and moved to their target OUs
Service Control PoliciesAuthored in service-control-policies/, attached at root/OU/account level
Delegated administratorsRegisters the accounts in delegated-admins.ts: the security account as delegated administrator for CloudTrail, IAM, IAM Access Analyzer, Config, GuardDuty, Security Hub, Inspector, and Macie, and the landing zone account for CloudFormation StackSets
StackSets delegated adminRegisters the landing zone account as the CloudFormation StackSets delegated administrator so it can run self-managed and service-managed StackSets
Landing zone account bootstrapThrough LandingZoneBootstrapStackSet: CDK toolkit resources, regional landing-zone asset buckets, and the landingzone GitHub Actions deploy role in the landing zone account
Cross-account read roleA read role so the landing zone account can read this stack's outputs at deploy time
Management StackSet exec roleA management-account StackSet execution role scoped to the landing zone account, so self-managed StackSets can still target the management account
GitHub Actions OIDC providerGitHubActionsOidcConstruct, creates the OIDC provider and GitHubActionsServiceRole, scoped to your repository
Alternate contactsApplied to every account via SetAlternateContactConstruct
Marketing email unsubscribeUnsubscribes account root emails from AWS marketing mail via UnsubscribeMarketingMailsConstruct
Management-account drift detectionDaily CloudFormation drift detection over the landing zone's own StackSets and stacks in the management account, via DetectCloudFormationDriftConstruct
Close-account reconcileWhen the organization structure includes CloseAccountOU, an 8-hour reconcile that closes any active accounts in that OU, via CloseAccountConstruct
Organization stack outputsEvery OU ID as a <Key>Id output, plus an account <Key>Id output for each account marked publishAccountIdOutput

LandingZoneBootstrapStackSet is a service-managed StackSet the organization phase targets at the Infrastructure OU intersected with the LandingZoneAccount. It exists so the landing zone account has CDK toolkit resources and asset buckets before the landing-zone phase runs. See Delegated Administrators for what gets registered here.

Landing-zone phase: LandingZoneFoundationStack

Deploys from the landing zone account. It prepares the shared infrastructure that account-provisioning StackSets depend on, and completes the one-time management-account provisioning through a self-managed StackSet.

What it createsDetails
StackSet IAM rolesAdministration and execution roles for self-managed StackSets, created or imported under their conventional names
Regional asset bucketsImports the regional landing-zone asset buckets that the organization phase created
LogArchiveStackSetCloudTrail log buckets in the log archive account
CentralAlertsStackSetThe shared CloudTrail notifications SNS topic in the security account
ProvisionManagementStackSetManagement-account secure defaults and the optional AWS Organizations account quota request (the management account cannot receive service-managed StackSets, so this self-managed StackSet handles it)
Landing-zone-account drift detectionDaily CloudFormation drift detection over the landing zone's own StackSets and stacks in this account. Runs directly from this stack, not through a StackSet, because it only needs to exist once per CloudFormation administrator account
Optional ExternalAccessStackSetGrants a third-party account admin access across the organization (only when externalAdmins is set in settings)

ProvisionManagementStackSet targets the management account directly and does two things: it applies the secure-defaults baseline (the management account is excluded from service-managed StackSets) and, when organizationAccountLimit is set, requests the AWS Organizations maximum-accounts quota. It always deploys after LogArchiveStackSet and CentralAlertsStackSet. IAM centralized root access is no longer applied here; it is enabled org-wide from the security account by OrganizationSecurityStackSet.

CloudFormation drift detection runs in both administrator accounts: this stack watches the landing zone account, and the organization phase watches the management account. The close-account reconcile runs in the organization phase alongside the management-account drift detection. See Constructs for the drift-detection and close-account constructs.

Landing-zone phase: LandingZoneAccountProvisioningStack

Also deploys from the landing zone account, after the foundation stack. It rolls out the account baseline across your accounts. Member-account StackSets are service-managed and run with CallAs: DELEGATED_ADMIN; the account-targeted StackSets (OrganizationSecurityStackSet, SecurityHubV2StackSet) are self-managed.

StackSetTargetsDetails
AccountSecurityStackSetAll member accounts (root OU), all configured regionsPer-account hardening with no org-wide control: deletes default VPCs, enables EBS encryption by default, hardens default security groups, configures SSM service settings, sets S3 Block Public Access and password policy
OrganizationSecurityStackSetSecurity account, all configured regionsOrganization-wide security run from the security account: the single AWS Organizations CloudTrail trail (with the Athena table and 14 CIS alarms), IAM centralized root access, and the IAM Access Analyzer external access analyzer
CostControlStackSetAll member accounts (root OU), primary regionAWS Budgets alerts and Cost Anomaly Detection with SNS notifications
CdkBootstrapStackSetDevelopment and Production OUs, all configured regionsCDK bootstrap roles, asset bucket, ECR repository, and a daily asset cleaner for CDK deployments
ServiceQuotasStackSetDevelopment, Production, and Security OUs, all configured regionsQuota increase requests, Lambda concurrent executions (L-B99A9384) by default
SecurityHubV2StackSetSecurity account, primary regionOrganization-wide Security Hub CSPM, GuardDuty, Inspector, and Macie configuration, managed from the delegated administrator account

A single organization trail, created from the security account, covers every account in the organization, including the management account. There are no per-account trails.

The organization output contract

LandingZoneOrganizationStack publishes every OU ID as a <Key>Id CloudFormation stack output (e.g. SecurityOUId), plus an account <Key>Id output for each account marked publishAccountIdOutput: true in the organization structure (e.g. SecurityAccountId). The foundation package reads these back and exposes them to the landing-zone stacks as typed orgVars properties.

Because the landing-zone stacks run in a different account, the read is cross-account and happens at deploy time. OU IDs are always available; an account ID is available only when its account opts in. The references resolve during deployment rather than at synth, and the only ordering requirement is that the organization phase deploys before the landing-zone phase that consumes its outputs, which the fixed phase order guarantees.

The output contract is bounded by the CloudFormation per-stack output limit. This is why account IDs are opt-in: publishing one output per account would exhaust the budget as the organization grows. A very large organization should split the contract or move dynamic metadata to a registry backend before reaching that boundary.

Enabling and disabling StackSets

Each StackSet is registered with a landingZone.createStackSet(...) call in its deployment stack. To disable a StackSet, remove (or comment out) its createStackSet block and redeploy. CloudFormation deletes the StackSet and its stack instances. To re-enable it, add the block back. See Customize StackSets for the full workflow.

Key dependencies to respect:

  • ProvisionManagementStackSet must deploy after LogArchiveStackSet and CentralAlertsStackSet
  • OrganizationSecurityStackSet consumes the log archive bucket and notifications topic that the foundation stack's StackSets create, plus the CloudTrail, IAM, and IAM Access Analyzer delegated-admin registrations owned by the organization phase, so keep those in place whenever it is enabled
  • SecurityHubV2StackSet relies on the organization phase having registered the security account as the delegated administrator for GuardDuty, Security Hub, Inspector, and Macie
  • The management account is excluded from service-managed StackSets and receives its secure-defaults baseline and optional account-quota request through ProvisionManagementStackSet; its CloudTrail coverage and IAM centralized root access both come from OrganizationSecurityStackSet