The landing zone rolls out its account baseline through CloudFormation StackSets. Which StackSets deploy, and to which accounts, OUs, and regions, is controlled by createStackSet calls in two files under src/stacks/. The StackSet implementations themselves live in src/stacksets/ and are separate from the targeting logic.
For a full inventory of what each StackSet deploys, see the StackSets reference.
The two stack files that control deployment
| File | Phase | Governs |
|---|---|---|
src/stacks/landing-zone-foundation-stack.ts | 2 | LogArchiveStackSet, CentralAlertsStackSet, ProvisionManagementStackSet |
src/stacks/landing-zone-account-provisioning-stack.ts | 3 | SecureDefaultsStackSet, CloudTrailStackSet, CostControlStackSet, CdkBootstrapStackSet, ServiceQuotasStackSet, SecurityHubV2StackSet |
Do not edit the StackSet implementation files in src/stacksets/ to change targeting. Only edit the target and regions arguments in the stack files above.
Disabling a StackSet
To disable a StackSet, comment out or remove its createStackSet block from the relevant stack file and redeploy. CloudFormation deletes the StackSet and removes its stack instances from all target accounts.
// Disable CostControlStackSet by commenting out the block:
// landingZone.createStackSet(this, {
// name: 'CostControlStackSet',
// description: 'Set up cost control measures for organization accounts',
// stackSetStack: new CostControlStackSetStack(this, 'CostControlStackSetStack', {
// securityAccountEmail,
// }),
// target: StackSetTarget.fromOrganizationalUnits({
// regions: [this.region],
// organizationalUnits: [orgVars.RootOUId],
// }),
// });
To re-enable it, uncomment the block and redeploy.
Dependencies to respect:
ProvisionManagementStackSetdeclares an explicitdependencies: [logArchiveStackSet, centralAlertsStackSet], so it always deploys after both. It imports the centralized CloudTrail delivery bucket from the log archive account and the CloudTrail notification topic from the security account, which those two StackSets create.SecurityHubV2StackSet(Phase 3) relies on the delegated-administrator registrations thatProvisionManagementStackSet(Phase 2) creates for Security Hub, GuardDuty, Inspector, and Macie. Because the two run in separate phases, the phase split enforces this ordering rather than adependenciesentry, so keepProvisionManagementStackSetenabled wheneverSecurityHubV2StackSetis.SecurityHubV2StackSetreceives its GuardDuty and Macie member accounts directly (resolved from your organization structure), so it owns member association itself.SecureDefaultsStackSetcovers member accounts through a service-managed StackSet, while the management account receives the same hardening from theSecureDefaultsConstructinsideProvisionManagementStackSet. Disabling one without the other leaves a gap in coverage.
Changing OU and account targets
Each createStackSet call takes a target that controls where the StackSet deploys. The OU and account IDs come from orgVars (the SSM-published IDs of your organization structure). Two targeting patterns are available:
Target whole OUs or the root (service-managed):
target: StackSetTarget.fromOrganizationalUnits({
regions: [this.region],
organizationalUnits: [orgVars.RootOUId],
}),
New accounts that join the targeted OU automatically receive the StackSet instance; accounts that leave have it removed. Swap orgVars.RootOUId for any OU ID from your organization structure, for example [orgVars.DevelopmentOUId, orgVars.ProductionOUId] to limit a StackSet to workload accounts only.
Narrow to specific accounts within an OU (service-managed with intersection):
target: StackSetTarget.fromOrganizationalUnits({
organizationalUnits: [orgVars.RootOUId],
intersectionAccounts: [orgVars.SecurityAccountId],
regions: [this.region, ...secondaryRegions],
}),
The LogArchiveStackSet and CentralAlertsStackSet use this pattern: they target the root OU but intersect to a single account, so only the log archive or security account receives the StackSet. (SecurityHubV2StackSet and ProvisionManagementStackSet instead target their account directly with fromAccounts, which makes them self-managed.)
Target explicit accounts (self-managed):
target: StackSetTarget.fromAccounts({
regions: [this.region, ...secondaryRegions],
accounts: [settings.managementAccountId],
}),
Use this for StackSets that must reach the management account. Service-managed StackSets cannot deploy to the management account, so these require deploymentType: landingZone.selfManagedDeploymentType. Self-managed StackSets need the StackSet IAM roles that LandingZoneFoundationConstruct creates.
Changing regions
The regions array on each target controls which regions receive a StackSet instance. Most StackSets deploy only to the primary region ([this.region]). Region-sensitive StackSets (secure defaults and central alerts) also cover secondaryRegions from your settings.
To add a region to a specific StackSet:
target: StackSetTarget.fromOrganizationalUnits({
regions: [this.region, ...secondaryRegions, 'ap-southeast-1'],
organizationalUnits: [orgVars.RootOUId],
}),
Adding a region that isn't in landing-zone-settings.ts's secondaryRegions is valid, but the region guardrail SCP may block API calls in that region unless you also add it to secondaryRegions. See Landing Zone Settings for how regions are configured.
Preview and deploy
After any targeting change, preview the diff first:
pnpm run management:diff
Then deploy:
pnpm run management:deploy
CloudFormation handles adding and removing StackSet instances as the target changes. Removing an OU from a target removes stack instances from all accounts currently in that OU; adding one deploys instances to all accounts already there.