A lean, CIS-aligned AWS multi-account landing zone for an early-stage startup (fictional AcmeCorp), generated by Merlin Studio from a single intent spec and emitted in two infrastructure-as-code formats.
This repository is a reference example — it shows what Merlin produces for a simple profile: the minimum viable governance baseline (org + security/log/audit accounts, one workload account, CIS controls, GitHub Actions OIDC) without the multi-region, PHI-isolation, or advanced-security weight a regulated zone carries.
Not a turnkey deployment. Real AWS identifiers are stubbed as
PLACEHOLDER_*tokens and all contact addresses use the reservedexample.comdomain. SeePLACEHOLDERS.mdbefore attempting to deploy.
| Organization | AcmeCorp (fictional startup) |
| Profile | simple (startup) |
| Compliance | CIS |
| Home region | us-east-2 (single region) |
| CI/CD | GitHub Actions — keyless OIDC deploy role scaffolded |
| Accounts | Management, LogArchive, Audit + one Workload account |
| Security scorecard | 100/100 (A+) — 150 compliance checks + 138 Checkov checks, 0 failures |
| Architecture scorecard | 100/100 (A) |
The same intent compiles to two independent deployment artifacts. Pick the one that matches your stack:
| Format | Folder | What it is | Best for |
|---|---|---|---|
| LZA | aws-lza/ |
AWS Control Tower + Landing Zone Accelerator (declarative YAML) | Teams standardizing on AWS-native governance |
| Terraform tfvars | aws-tfvars/ |
Variable definitions (*.auto.tfvars) consumed by Terraform / OpenTofu landing-zone modules |
Teams running their own Terraform / OpenTofu module stack |
Shared docs at the repository root:
architecture.mmd— Mermaid topology diagram (rendered below)ARCHITECTURE_SCORECARD.md/SECURITY_SCORECARD.mdCOMPLIANCE_UPGRADES.md— every value a compliance framework forcedDEPLOYMENT_GUIDE.md— deploy-and-verify runbook per format
.
├── README.md (this file)
├── DEPLOYMENT_GUIDE.md Step-by-step deploy for each format
├── architecture.mmd Mermaid topology diagram
├── ARCHITECTURE_SCORECARD.md Design-quality scorecard
├── SECURITY_SCORECARD.md Compliance + Checkov scorecard
├── COMPLIANCE_UPGRADES.md Compliance-driven changes
├── PLACEHOLDERS.md Tokens to replace before deploy
├── aws-lza/ Format 1: AWS Control Tower + Landing Zone Accelerator (YAML)
│ ├── global-config.yaml
│ ├── accounts-config.yaml
│ ├── organization-config.yaml
│ ├── iam-config.yaml
│ ├── network-config.yaml
│ ├── security-config.yaml
│ └── service-control-policies/, kms/, tag-policies/, ssm-documents/ (supporting JSON/YAML)
└── aws-tfvars/ Format 2: Terraform / OpenTofu variable definitions
├── accounts.auto.tfvars
├── organizations.auto.tfvars
├── iam.auto.tfvars
├── network.auto.tfvars
├── security.auto.tfvars
├── cloudtrail.auto.tfvars
├── kms.auto.tfvars
└── backup.auto.tfvars
graph TD
%% AWS Organizations
Org[AWS Organizations<br/>AcmeCorp]:::org
%% OUs
Org --> OU_Security[Security OU]:::ou
Org --> OU_Workloads[Workloads OU]:::ou
%% Mandatory accounts under Security
OU_Security --> Acct_LogArchive[LogArchive<br/>Account]:::account
OU_Security --> Acct_Audit[Audit<br/>Account]:::account
OU_Workloads --> Acct_Workload[Workload<br/>Account]:::account
%% Security services (run from Audit account)
Acct_Audit -.delegated.-> GuardDuty[GuardDuty]:::service
Acct_Audit -.delegated.-> SecurityHub[Security Hub]:::service
Acct_Audit -.delegated.-> Config[AWS Config<br/>Aggregator]:::service
Acct_Audit -.delegated.-> AccessAnalyzer[Access Analyzer]:::service
%% Logging (LogArchive account)
Acct_LogArchive --> CentralLogsBucket[(S3 Central<br/>Logs Bucket)]:::s3
Acct_LogArchive --> CloudTrail[Org CloudTrail<br/>multi-region: true]:::service
CloudTrail --> CentralLogsBucket
Config --> CentralLogsBucket
%% Encryption
CentralLogsBucket -.encrypts with.-> CMK_Logs[KMS CMK<br/>central-logs-key]:::kms
CloudTrail -.encrypts with.-> CMK_Logs
%% VPCs
Workload_acct[Workload] --> VPC_Main[main<br/>10.0.0.0/16]:::vpc
%% IAM Identity Center
Org -.via.-> IdC[IAM Identity Center<br/>SSO Permission Sets]:::iam
%% Styling
classDef org fill:#ff9900,stroke:#232f3e,color:#000,stroke-width:2px
classDef ou fill:#ffd180,stroke:#232f3e,color:#000
classDef account fill:#ffe0b2,stroke:#232f3e,color:#000
classDef service fill:#0073bb,stroke:#232f3e,color:#fff
classDef s3 fill:#e8f5e9,stroke:#1b5e20,color:#000
classDef kms fill:#fff9c4,stroke:#f57f17,color:#000
classDef network fill:#bbdefb,stroke:#0d47a1,color:#000
classDef vpc fill:#e3f2fd,stroke:#1565c0,color:#000
classDef iam fill:#d1c4e9,stroke:#311b92,color:#000
| Name | Purpose | OU |
|---|---|---|
| Management | AWS Organizations payer + LZA control plane | Root |
| LogArchive | Central log archive (CloudTrail org trail, Config) | Security |
| Audit | Security tooling delegated administrator | Security |
| Name | OU | Description |
|---|---|---|
| Workload | Workloads | Application account — VPCs and workload resources live here, never in Management. |
This zone is configured to meet CIS baseline requirements. Controls applied:
- CloudTrail organization trail with KMS-CMK encryption and log file validation
- AWS Config recorder + aggregator delegated to the Audit account
- GuardDuty with
auto_enable = truefor all org members - Security Hub with framework-aligned standards subscriptions
- IAM password policy: min length 14, rotation every 90 days
- KMS CMKs with automatic key rotation enabled (CIS 3.8). The tfvars format sets a 90-day rotation period (stricter than CIS requires); LZA uses AWS-managed annual rotation
- S3 default encryption + SSL-only bucket policies
- EBS default encryption and IMDSv2 required on all EC2 instances
- VPC Flow Logs on every VPC, all-traffic, with CloudWatch + S3 destinations
- Search and replace
PLACEHOLDER_tokens — account emails, AWS account IDs, and the org ID. SeePLACEHOLDERS.md. - Pre-create your AWS Organization with a Management account. LZA / Terraform cannot bootstrap the org itself.
- Enable AWS Organizations trusted service access from the management account —
or confirm AWS Control Tower already has — before deploying:
And enable the organization policy types the zone uses:
aws organizations enable-aws-service-access --service-principal cloudtrail.amazonaws.com aws organizations enable-aws-service-access --service-principal config.amazonaws.com aws organizations enable-aws-service-access --service-principal controltower.amazonaws.com aws organizations enable-aws-service-access --service-principal guardduty.amazonaws.com aws organizations enable-aws-service-access --service-principal securityhub.amazonaws.com aws organizations enable-aws-service-access --service-principal sso.amazonaws.com
Skipping this breaks org-wide CloudTrail, the Config aggregator, GuardDuty / Security Hub org auto-enable, and IAM Identity Center.aws organizations enable-policy-type --root-id <ROOT_ID> --policy-type SERVICE_CONTROL_POLICY aws organizations enable-policy-type --root-id <ROOT_ID> --policy-type TAG_POLICY
- Enable AWS IAM Identity Center in the management account if you want SSO permission sets to provision.
- Bootstrap state storage for Terraform / OpenTofu (S3 + DynamoDB lock) if you
deploy the
aws-tfvarsformat — seeDEPLOYMENT_GUIDE.md.
Merlin Studio uses a compile-AI approach. LLMs run at design time to encode AWS best-practice patterns, compliance-framework requirements, and discovery-driven defaults into a static rules engine. At generation time every value is derived deterministically from the discovery answers — no LLM call happens during generation, so the same answers always produce the same artifact.
Deeper reading: "Compiled AI for GCP Landing Zones" → dev.to/boristep. The methodology is identical for the AWS pipeline.
Values in this spec come from up to five layers, with later layers winning on conflict:
1. Schema defaults ← floor: a value exists for every field
2. Profile defaults ← simple / standard / advanced — broad shape
3. Compliance overlays ← HIPAA / CIS / PCI / FedRAMP add-ons (per framework)
4. Discovery overlays ← driven by YOUR answers (multi-region, encryption, ...)
5. User edits ← anything you typed in the wizard ALWAYS wins
Arrays append by name — a compliance overlay adding a required account does not erase the accounts you selected. For scalars, discovery overlays overwrite profile defaults (the discovery answer is the more specific signal); compliance overlays only fill empty slots; your saved values are merged last and override everything.
The rules-engine trace — what each overlay added, why, and what triggered it.
| Section | Overlay | Triggered by | Rationale |
|---|---|---|---|
03_iam_model |
github_actions_oidc_and_deploy_role |
existing_cicd contains 'github_actions' |
Discovery declared GitHub Actions as an existing CI/CD platform. Scaffold the GitHub OIDC provider and a Terraform deploy role so the pipeline has a keyless federated path to AWS — otherwise the team must hand-build the OIDC provider + role. |
14_observability |
medium_availability_target_basic_observability |
availability_target in ['99.9', '99.95'] AND availability_requirements != 'very_high' |
99.9% / 99.95% targets need Synthetics + X-Ray but not the full Prometheus/Grafana stack. |
Licensed under the Apache License, Version 2.0 — see LICENSE.