CloudFormation StackSets let a single template deploy simultaneously to multiple accounts and regions. The landing zone uses StackSets to roll out its account baseline, so every account that joins a targeted OU automatically receives the full baseline without manual intervention. Each StackSet composes one or more single-purpose constructs from @towardsthecloud/cdk-landing-zone-constructs into the template it ships.
All landing-zone StackSets are created from the landing zone account, which the organization phase registers as the CloudFormation StackSets delegated administrator. The landing zone uses two permission models:
- Service-managed (default): CloudFormation manages the required IAM roles and targets OUs directly. New accounts that join a targeted OU receive the StackSet automatically. This model cannot deploy to the management account.
- Self-managed: used when the target is a specific account rather than an OU. It relies on the StackSet IAM roles the landing zone foundation creates, and it is the only model that can reach the management account.
At a glance
| StackSet | Stack | Permission | Deployed to |
|---|---|---|---|
| ObservabilityStackSet | Foundation | Self-managed | Observability account, primary Region |
| ProvisionManagementStackSet | Foundation | Self-managed | Management account, all configured Regions |
| OrganizationSecurityStackSet | Foundation | Self-managed | Security account, all configured Regions |
| FinOpsStackSet | Foundation | Self-managed | FinOps account, primary Region |
| AccountSecurityStackSet | Member accounts | Service-managed | All member accounts, all configured Regions |
| ResourceExplorerStackSet | Member accounts | Service-managed | All member accounts except FinOps, primary Region |
| CdkBootstrapStackSet | Member accounts | Service-managed | Development and Production OUs, all configured Regions |
| ServiceQuotasStackSet | Member accounts | Service-managed | Development, Production, and Security OUs, all Regions |
"Foundation" StackSets deploy from LandingZoneFoundationStack; "Member accounts" StackSets from LandingZoneMemberAccountsStack. Both stacks run in the landing-zone phase, from the landing zone account. Delegated administration for the security, observability, and FinOps services is registered earlier, in the organization phase, through delegated-admins.ts, so by the time these StackSets run the security account is already the delegated administrator for the security services, the observability account for CloudTrail, and the FinOps account for Compute Optimizer, Cost Optimization Hub, and Resource Explorer.
Foundation StackSets
These StackSets prepare the landing zone's own accounts and what they run for the whole organization. Each targets one account directly, so each is self-managed.
ObservabilityStackSet
Runs the organization's audit trail and routes its alerts from the observability account, which the organization phase registers as the CloudTrail and AWS User Notifications delegated administrator. One AWS Organizations trail covers every account in the organization, including the management account, so there are no per-account trails.
| Resource | Details |
|---|---|
| Organization trail | Multi-Region organization trail with log file validation and global service events, covering every account in the organization including the management account |
| Log and access-log buckets | The bucket the trail delivers to and a second bucket for its S3 server access logs. Both expire their objects after the retention period |
| KMS key | Rotating key that encrypts the delivered log files |
| Athena querying | A Glue database (cloudtrail), an Athena cloudtrail_logs table over the log bucket, and a cloudtrail workgroup with a local results bucket |
| CIS alarms | The 14 CIS AWS Foundations Benchmark alarms. The StackSet enables CloudWatch Logs delivery so the alarms ship by default |
| Alerts topic | Encrypted SNS topic security-alerts that the alarms notify, subscribed to the security contact email |
| Security alerts | A User Notifications configuration that emails the security contact high and critical GuardDuty, Inspector, and Macie findings from every account and active Region, each finding once |
| Operations alerts | A User Notifications configuration that emails the operations contact CloudWatch alarms entering ALARM, the CIS alarms included, and failed CloudFormation stack operations from every account and active Region |
Data events (S3, Lambda, DynamoDB) and CloudTrail Insights are opt-in construct props, disabled by default. The trail is multi-Region by itself, and the User Notifications configurations cover every active Region from one place, so the StackSet deploys to the primary Region only.
Things to know:
- Activate each alert address: after the first
landingzonedeployment, AWS sends a confirmation email to the security and operations contacts from alternate-contacts.ts. AWS emails an address no alerts until it is activated from that email. Changing an address sends the new one its own confirmation email to activate. Removing the StackSet keeps the notification configurations and contacts, so adding it back needs no new activation. - Alert scope: the alerts cover every account in the organization, including accounts you create later, and each audience gets one email per 5 minutes. Security Hub's own control findings stay in the Security Hub console, because User Notifications doesn't offer Security Hub as a source. AWS stores and processes the notifications in
us-east-1, which the Region guardrail allows for User Notifications. - Retention: set
auditLogRetentionin landing-zone-settings.ts to change how long both buckets keep their objects. The default is 365 days. - Removal:
auditLogRemovalPolicyin the same file decides what happens to the audit logs when the StackSet is removed. The default,RETAIN, keeps the trail, both buckets, and the key, so existing log files stay readable. The CloudWatch Logs delivery and the CIS alarms are removed. A reinstall creates new buckets and a new key next to the retained ones.DESTROYdeletes the buckets, the trail, and the key; use it only for an organization whose audit logs are disposable.
Composes: OrganizationTrailConstruct, EncryptedSNSTopicConstruct, OrganizationNotificationsConstruct. Target: Observability account, primary Region. Targets the observability account directly (self-managed). Deployed by: LandingZoneFoundationStack, after the organization phase registers the observability account as the CloudTrail and User Notifications delegated administrator.
ProvisionManagementStackSet
Provisions the management account. Service-managed StackSets cannot deploy to the management account, so this self-managed StackSet handles what only reaches it this way: the secure-defaults baseline, the organization-wide Compute Optimizer and Cost Optimization Hub enrollment, the management account's own Resource Explorer indexes, and the optional AWS Organizations account-quota request. Delegated administrator registration is owned by the organization phase; IAM centralized root access comes from the Organization Security StackSet, and the management account's CloudTrail coverage from the organization trail in the Observability StackSet.
| Resource | Details |
|---|---|
| Secure defaults | Deletes default VPCs, enables EBS encryption, hardens default security groups, configures SSM service settings, sets S3 Block Public Access and password policy |
| Compute Optimizer and Cost Optimization Hub enrollment | Opts the management account and every member account in to both services in the primary Region |
| Resource Explorer indexes | An index in each configured Region with the aggregator index in the primary Region, the same as the Resource Explorer StackSet sets up for member accounts |
| Organizations account quota | When organizationAccountLimit is set in settings, requests the AWS Organizations maximum-accounts quota for the account |
Only the management account can enroll member accounts, which is why enrollment lives here and not in the FinOps account. Removing this StackSet keeps the accounts enrolled, and the management account cannot opt member accounts out, so each account opts out on its own: aws compute-optimizer update-enrollment-status --status Inactive for Compute Optimizer, and clearing Enable Cost Optimization Hub under Cost Management preferences for the Hub. Opting out deletes that account's recommendations. Compute Optimizer's first analysis can take up to 24 hours (metrics analyzed by Compute Optimizer). The landing zone does not turn on Compute Optimizer's paid enhanced infrastructure metrics. Removing the StackSet also keeps the Resource Explorer indexes.
Composes: SecureDefaultsConstruct, CostOptimizationEnrollmentConstruct, ResourceExplorerConstruct, and (when organizationAccountLimit is set) IncreaseServiceQuotaConstruct.
Target: Management account, all configured Regions (enrollment and the account quota request run in the primary Region only).
Deployed by: LandingZoneFoundationStack.
OrganizationSecurityStackSet
Provisions the organization-wide security measures that must run from the security account, which the organization phase registers as the IAM, IAM Access Analyzer, Security Hub, GuardDuty, Inspector, and Macie delegated administrator: IAM centralized root access, the IAM Access Analyzer organization external access analyzer, and unified Security Hub V2 management of Security Hub CSPM, GuardDuty, Inspector, and Macie. It is the organization-wide counterpart to AccountSecurityStackSet.
| Resource | Details |
|---|---|
| Centralized root access | Enables IAM centralized root access for organization member accounts, applied once from the primary Region |
| Access Analyzer | An IAM Access Analyzer organization external access analyzer in every configured Region, reporting resources shared with principals outside the organization (satisfies Security Hub control IAM.28 / CIS v3.0.0 1.20) |
| Security Hub V2 hub | The Security Hub V2 hub, enabled in every configured Region, with cross-Region aggregation |
| Security Hub CSPM | Central configuration, the AWS Config service-linked recorder, and the organization standards policy |
| GuardDuty | An organization policy that enables GuardDuty and its protection plans in every configured Region, in every account |
| Inspector | The organization scanning policy for EC2, ECR, Lambda, and code repositories |
| Macie | Organization auto-enable and automated sensitive data discovery |
In the starter defaults, all four security services are enabled (enabled: true on each options block). To turn one off, for example to save cost on a service you don't need, set enabled: false on its options block (cspmOptions, guardDutyOptions, inspectorOptions, or macieOptions) in src/config/security-services.ts and redeploy. Keep all four options blocks and set their enabled booleans explicitly. Disabling a service preserves the prerequisites for re-enablement, and the delegated administrator's unified Security Hub V2 hub stays enabled.
Accounts in the close-account OU, which are waiting to be closed, have these services turned off or left unmanaged; accounts in the rest of the Suspended OU keep the baseline. GuardDuty and Macie member onboarding does not depend on published account IDs: they cover the eligible member accounts of the organization, and a workload account never needs publishAccountIdOutput just to be covered.
Things to know:
- GuardDuty: accounts cannot change a protection plan the organization policy manages. Disabling GuardDuty keeps the policies and turns it off; removing a Region turns GuardDuty off there. The deployment fails and names the accounts that did not reach the desired state.
- Macie: disabling Macie suspends it for current members so it stops billing.
- Removal: removing the StackSet turns GuardDuty off and disables Security Hub V2, and leaves the Security Hub delegated administrator registration and the classic Security Hub hub in the security account in place. IAM centralized root access stays enabled.
Composes: CentralizedRootAccessConstruct, IamAccessAnalyzerConstruct, and SecurityHubV2Construct, which composes SecurityHubCspmConstruct, GuardDutyConstruct, InspectorConstruct, and MacieConstruct. Target: Security account, all configured Regions. Centralized root access and Security Hub V2 run from the primary Region; the external access analyzer deploys in every Region. Targets the security account directly (self-managed). Deployed by: LandingZoneFoundationStack. Relies on the IAM, IAM Access Analyzer, and security-service delegated-admin registrations owned by the organization phase.
FinOpsStackSet
Provisions organization-wide FinOps capabilities from the FinOps account, which the organization phase registers as the delegated administrator for Compute Optimizer, Cost Optimization Hub, and Resource Explorer. Enrollment of the organization itself comes from ProvisionManagementStackSet.
| Resource | Details |
|---|---|
| Cost Optimization Hub preferences | Estimates savings after discounts and shows them to member accounts, which member accounts need to view cost efficiency. Commitment preferences stay yours to manage, and removing the StackSet keeps the preferences |
| Resource Explorer indexes | An index in each configured Region with the aggregator index in the primary Region, the same as the Resource Explorer StackSet sets up for the other member accounts |
| Organization view | A Resource Explorer view that searches every account in the organization, set as the FinOps account's default view in the primary Region, so cost analysis can find any resource |
The view is created after the account's own indexes. Removing the StackSet deletes the view and keeps the indexes; a reinstall creates the view again. Cost Explorer and a custom billing view shared with the FinOps account are manual prerequisites for analyzing organization-wide costs there; see Enable Cost Explorer. Organizations that use AWS Billing Transfer as a bill source get before-discounts savings estimates instead.
Composes: CostOptimizationHubPreferencesConstruct, ResourceExplorerConstruct.
Target: FinOps account, primary Region. Targets the FinOps account directly (self-managed).
Deployed by: LandingZoneFoundationStack, after ProvisionManagementStackSet has enrolled the organization.
Member-account StackSets
These StackSets target OUs, so every account that joins a targeted OU receives them automatically. They are service-managed and use the shared fast rollout settings described in Customize StackSets.
AccountSecurityStackSet
Hardens each member account individually with security settings that have no organization-wide control, in every configured Region. It is the per-account counterpart to OrganizationSecurityStackSet, which configures org-wide services once from the security account. It currently applies the secure account defaults; more per-account hardening will be added over time.
| Resource | Details |
|---|---|
| Default VPC deletion | Removes the default VPC in each Region so workloads must use explicitly created VPCs |
| EBS encryption | Enables EBS encryption by default for all new volumes |
| EBS snapshot sharing | Blocks all public sharing of EBS snapshots, including a setting configured outside CloudFormation |
| Security group hardening | Strips all rules from the default security group of any newly created VPC |
| SSM service settings | Blocks public sharing of SSM documents and routes automation script logs to CloudWatch |
| S3 Block Public Access | Enables account-level S3 Block Public Access (global settings Region only) |
| Password policy | Sets the IAM account password policy: 18 characters, 90-day expiry, reuse prevention (global settings Region only) |
Composes: SecureDefaultsConstruct.
Target: All member accounts (root OU), all configured Regions. The management account gets the same hardening via ProvisionManagementStackSet.
Deployed by: LandingZoneMemberAccountsStack.
ResourceExplorerStackSet
Turns on AWS Resource Explorer in every member account under the root OU, suspended accounts included, so the FinOps account's organization view can search every account and Region. Each account gets an index in every configured Region, with the aggregator index in the primary Region.
The StackSet excludes the FinOps account, which FinOpsStackSet indexes together with its organization view, and the management account, which ProvisionManagementStackSet covers. Resource Explorer itself is free; see the AWS pricing note.
Things to know:
- Existing indexes: indexes that already exist, for example from the console, are adopted, and existing views are never changed.
- Aggregator index in another Region: if an account already has its aggregator index in a different Region, cross-Region search can take up to a day to return after the deployment. See Promoting a local index to be the aggregator index.
- Region guardrail: the Region-deny SCP the starter ships does not block the landing zone's own Resource Explorer automation.
- Removal: removing the StackSet or a Region keeps the indexes.
Composes: ResourceExplorerConstruct. Target: All member accounts (root OU) except the FinOps account, primary Region. One deployment per account manages every configured Region. Deployed by: LandingZoneMemberAccountsStack.
CdkBootstrapStackSet
Bootstraps your workload accounts for CDK deployments and keeps the bootstrap assets tidy. The StackSet mirrors the default cdk bootstrap deployment (qualifier hnb659fds) so the CDK CLI and DefaultStackSynthesizer work unchanged in the target accounts, with no synthesizer configuration in your workload apps.
| Resource | Details |
|---|---|
| CDK bootstrap IAM roles | cdk-hnb659fds-cfn-exec-role, -deploy-role, -file-publishing-role, -image-publishing-role, -lookup-role |
| CDK assets S3 bucket | cdk-hnb659fds-assets-{account}-{region}, versioned, SSL-only, stores templates and file assets |
| CDK assets ECR repository | cdk-hnb659fds-container-assets-{account}-{region}, immutable tags, stores Docker image assets |
| Bootstrap version SSM | /cdk-bootstrap/hnb659fds/version so the CDK CLI can validate the environment |
| Asset cleaner | Daily removal of unreferenced S3 and ECR assets older than 30 days |
The starter sets assetRemovalPolicy to DESTROY (overriding the construct's RETAIN default), so tearing down the StackSet removes the bootstrap buckets and repositories rather than retaining them.
Things to know:
- Brownfield accounts: an account that already has a manually created
CDKToolkitstack collides on the fixedcdk-hnb659fds-*resource names. Delete the old stack, itscdk-hnb659fds-assets-*bucket, and empty its ECR repository before the StackSet rolls out to that account. - Workload OUs only: this StackSet targets the Development and Production OUs, and excludes the landing zone account.
Composes: CdkToolkitConstruct, CdkToolkitCleanerConstruct. Target: Development and Production OUs, all configured Regions, excluding the landing zone account. Deployed by: LandingZoneMemberAccountsStack.
ServiceQuotasStackSet
Requests configured service quota increases in each targeted account. Regional requests apply in each configured Region; global requests apply once per account. Requests are idempotent (the construct skips a request when the same or a higher value is already requested) and asynchronous, so the requested value may not be active immediately after the StackSet deploys.
| Quota | Service | Requested value | Default |
|---|---|---|---|
Lambda concurrent executions (L-B99A9384) | lambda | 2000 | On |
Configure serviceQuotaRequests in src/config/service-quotas.ts. Each entry has a stable key and supplies quotaCode, serviceCode, and desiredValue, with optional scope; add entries there to request other quotas. The AWS Organizations account limit is handled separately: when you set organizationAccountLimit in landing-zone-settings.ts, the Provision Management StackSet requests it against the management account instead, since that quota is global rather than per-workload-account.
Composes: IncreaseServiceQuotaConstruct. Target: Development, Production, and Security OUs, all configured Regions. Deployed by: LandingZoneMemberAccountsStack.