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, running with
CallAs: DELEGATED_ADMINfrom the landing zone account. 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 |
|---|---|---|---|
| LogArchiveStackSet | Foundation | Self-managed | Log archive account, primary region |
| CentralAlertsStackSet | Foundation | Self-managed | Security account, all configured regions |
| ProvisionManagementStackSet | Foundation | Self-managed | Management account, all configured regions |
| AccountSecurityStackSet | Provisioning | Service-managed | All member accounts, all configured regions |
| OrganizationSecurityStackSet | Provisioning | Self-managed | Security account, all configured regions |
| CostControlStackSet | Provisioning | Service-managed | All member accounts, primary region |
| CdkBootstrapStackSet | Provisioning | Service-managed | Development and Production OUs, all configured regions |
| ServiceQuotasStackSet | Provisioning | Service-managed | Development, Production, and Security OUs, all regions |
| SecurityHubV2StackSet | Provisioning | Self-managed | Security account, primary region |
"Foundation" StackSets deploy from LandingZoneFoundationStack; "Provisioning" StackSets from LandingZoneAccountProvisioningStack. Both stacks run in the landing-zone phase, from the landing zone account. Delegated administration for the security 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.
Foundation StackSets
LogArchiveStackSet
Creates the centralized CloudTrail storage in the log archive account. Composes raw CDK resources rather than a baseline construct.
| Resource | Details |
|---|---|
| CloudTrail log S3 bucket | cloudtrail-logs-{account}, SSL-only, S3-managed encryption, public access blocked, 365-day expiry |
| Access logging bucket | cloudtrail-access-logs-{account} capturing S3 access logs for the CloudTrail bucket |
| Bucket policy | Scoped to the organization trail: writes allowed only for the fixed trail ARN under the AWSLogs/<organizationId>/ and AWSLogs/<managementAccountId>/ key paths, plus read access for the security account's Athena queries |
Both buckets use a DESTROY removal policy with object auto-deletion, so removing the StackSet cleans up the storage rather than stranding it.
Target: Log archive account, primary region. Targeted directly by the account's published LogArchiveAccountId output, which makes it self-managed.
Deployed by: LandingZoneFoundationStack. Must deploy before ProvisionManagementStackSet.
CentralAlertsStackSet
Creates the centralized CloudTrail notification topic in the security account. The organization trail's CIS alarms publish to this topic.
| Resource | Details |
|---|---|
| CloudTrail notifications topic | Encrypted SNS topic for CloudTrail notifications, subscribed to the security contact email |
Composes: EncryptedSNSTopicConstruct.
Target: Security account, all configured regions. Targeted directly by the account's published SecurityAccountId output, which makes it self-managed.
Deployed by: LandingZoneFoundationStack. Must deploy before ProvisionManagementStackSet.
ProvisionManagementStackSet
Provisions the management account. Service-managed StackSets cannot deploy to the management account, so this self-managed StackSet handles the two things that only reach it this way: the secure-defaults baseline and the optional AWS Organizations account-quota request. Delegated administrator registration is owned by the organization phase; the management account's CloudTrail coverage and its IAM centralized root access both come from the Organization Security StackSet, which runs org-wide from the security account.
| 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 |
| Organizations account quota | When organizationAccountLimit is set in settings, requests the AWS Organizations maximum-accounts quota for the account |
Composes: SecureDefaultsConstruct and (when organizationAccountLimit is set) IncreaseServiceQuotaConstruct.
Target: Management account, all configured regions.
Deployed by: LandingZoneFoundationStack, after LogArchiveStackSet and CentralAlertsStackSet.
Account-baseline 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 |
| 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: LandingZoneAccountProvisioningStack.
OrganizationSecurityStackSet
Provisions the organization-wide security measures that must run from the security account, which the organization phase registers as the CloudTrail, IAM, and IAM Access Analyzer delegated administrator: the single AWS Organizations CloudTrail trail, IAM centralized root access, and the IAM Access Analyzer organization external access analyzer. One 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 |
| KMS key | Rotating key in the security account that encrypts the delivered log files, scoped to the management-account trail ARN |
| Athena querying | A Glue database (cloudtrail), an Athena cloudtrail_logs table over the log archive bucket, and a cloudtrail workgroup with a local results bucket (30-day expiry) |
| CIS alarms | The 14 CIS AWS Foundations Benchmark alarms, publishing to the shared notifications topic. The StackSet enables CloudWatch Logs delivery so the alarms ship by default |
| 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, reporting resources shared with principals outside the organization (satisfies Security Hub control IAM.28 / CIS v3.0.0 1.20) |
Data events (S3, Lambda, DynamoDB) and CloudTrail Insights are opt-in construct props, disabled by default. The trail sends its logs to the centralized log archive bucket. The organization trail and centralized root access are organization/account global, so their resources are conditioned to the primary region; the external access analyzer is regional and deploys in every configured region.
Composes: OrganizationTrailConstruct, CentralizedRootAccessConstruct, IamAccessAnalyzerConstruct.
Target: Security account, all configured regions. Self-managed, targeted by the published SecurityAccountId output.
Deployed by: LandingZoneAccountProvisioningStack. Relies on the CloudTrail, IAM, and IAM Access Analyzer delegated-admin registrations owned by the organization phase and the log archive bucket created by the foundation stack.
CostControlStackSet
Sets up cost monitoring in every account with AWS Budgets and Cost Anomaly Detection.
| Resource | Details |
|---|---|
| AWS Budget | Monthly budget that alerts on actual and forecast spend |
| Cost Anomaly Detection | Monitor that alerts when an anomaly's total impact reaches 100% |
| SNS topic | Encrypted SNS topic budgets-notifications, subscribed to the security contact email |
AWS Budgets does not support cross-account SNS topics, so each account creates its own notification topic.
Composes: BudgetConstruct, CostAnomalyConstruct, EncryptedSNSTopicConstruct.
Target: All member accounts (root OU), primary region.
Deployed by: LandingZoneAccountProvisioningStack.
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 | Scheduled Lambda that deletes unreferenced S3 and ECR assets each day |
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, since those accounts don't run CDK workloads.
Composes: CdkToolkitConstruct, CdkToolkitCleanerConstruct.
Target: Development and Production OUs, all configured regions.
Deployed by: LandingZoneAccountProvisioningStack.
ServiceQuotasStackSet
Requests regional service quota increases in each targeted 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 |
EC2 Elastic IP addresses (L-0263D0A3) | ec2 | 10 | Off (commented out; uncomment to enable) |
The quota list is configurable in the StackSet, so you can add your own requests or enable the shipped-but-commented EC2 Elastic IP request. 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: LandingZoneAccountProvisioningStack.
SecurityHubV2StackSet
Configures the four organization-wide security services from the security account, which the organization phase has already registered as the delegated administrator for each. A single SecurityHubV2Construct coordinates Security Hub CSPM, GuardDuty, Inspector, and Macie behind one shared IAM role.
| Resource | Details |
|---|---|
| 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 | Organization auto-enable and protection plans |
| 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 services ship wired but disabled (enabled: false on each options block). The delegated-admin registration still happens in the organization phase, so when you're ready to turn a service on, you flip its options block (cspmOptions, guardDutyOptions, inspectorOptions, or macieOptions) in securityhub-v2-stackset-stack.ts and redeploy.
GuardDuty and Macie member onboarding does not depend on published account IDs. When you enable them, they discover the eligible member accounts from AWS Organizations at deploy time and associate them, excluding the delegated administrator, the management account, and Suspended OU accounts, so a workload account never needs publishAccountIdOutput just to be covered.
Composes: SecurityHubV2Construct.
Target: Security account, primary region.
Deployed by: LandingZoneAccountProvisioningStack. Depends on the organization phase having registered the delegated administrators.