Cloud Architecture & Landing Zones

Landing Zones & Control Tower

18 min Lesson 3 of 28

Landing Zones & Control Tower

A Landing Zone is the multi-account AWS environment that your entire organization runs inside. It is not a single service or a checkbox — it is the secure, governed foundation on which every workload, every team, and every compliance requirement sits. Getting it wrong at the start means retrofitting security controls onto hundreds of accounts under production pressure. Getting it right means your platform team can provision a new team environment in minutes with security built in by default.

This lesson covers the four pillars of a production Landing Zone: baseline account topology, Organizational Unit (OU) design, Service Control Policies (SCPs) as preventive guardrails, and centralized logging. These are not concepts used only at hyperscaler scale — they are the baseline expectation at any serious company from Series B onward.

Baseline Account Topology

The first principle of Landing Zone design: never run workloads in the management (root) account. The management account has unrestricted access to all member accounts. If it is compromised or misconfigured, everything in your organization is at risk. AWS recommends keeping it empty of workloads and restricting human access to near-zero.

A mature baseline topology uses at minimum these dedicated accounts:

  • Management Account — owns the AWS Organization. Only used by platform/cloud-ops. Hosts AWS Control Tower, AWS Organizations, consolidated billing, and nothing else. Human login is rare and requires MFA + break-glass process.
  • Log Archive Account — a write-once destination for all organization-wide logs: CloudTrail, AWS Config, VPC Flow Logs, and S3 Access Logs. Workload accounts can ship to it but cannot delete from it. Even organization admins should not have delete permission on the log bucket — enforce this with an S3 Object Lock policy.
  • Audit / Security Tooling Account — runs Security Hub, GuardDuty aggregator, Inspector, and your SIEM integration. Has read-only cross-account access into all member accounts. Security team owns this account; it is not shared with developers.
  • Shared Services Account — hosts centrally-shared infrastructure: Transit Gateway, Route 53 Resolver, internal CA (ACM PCA), shared AMI pipeline, artifact repositories (ECR, CodeArtifact). All workload accounts peer or attach through here.
  • Workload Accounts (per environment) — dev, staging, and prod are separate AWS accounts, not separate VPCs in the same account. Account-level isolation is the strongest blast radius control AWS offers: an IAM misconfiguration in dev cannot affect prod resources.
  • Network Account — owns the Transit Gateway and egress inspection (Network Firewall or third-party appliance). Centralizes routing policy without giving workload accounts control over the network fabric.
The single most impactful security decision in a Landing Zone is making each environment a separate account. IAM policies, resource-based policies, and VPC security groups all stop at the account boundary. A blast radius that could compromise a region is reduced to a single environment when accounts are properly separated.

OU Design: Organizing Accounts into Policies

AWS Organizations groups accounts into Organizational Units (OUs). OUs exist for one reason: to apply Service Control Policies (SCPs) consistently to a group of accounts without touching each account individually. A clean OU hierarchy makes SCP management tractable at hundreds of accounts.

A standard top-level OU structure recommended by AWS and adopted by most large organizations:

  • Root — applies baseline SCPs that apply to everyone, including the management account restrictions.
  • Infrastructure OU — contains the Log Archive, Audit, Shared Services, and Network accounts. SCPs here are permissive for platform tooling but block workload-like actions (no EC2 launch from Log Archive).
  • Workloads OU — subdivided into SDLC (dev/staging) and Production. Production-specific SCPs enforce stricter controls: no disabling CloudTrail, no public S3 buckets, no leaving allowed regions.
  • Sandbox OU — developer experimentation accounts. Aggressive cost limits via SCPs (block expensive instance families), mandatory auto-termination of resources, and no VPC peering to production networks.
  • Suspended OU — accounts being offboarded. An SCP attached here denies all actions, effectively freezing the account while it awaits deletion or audit.
Landing Zone OU hierarchy and baseline account topology Root OU Management Account only Infrastructure OU Platform tooling accounts Log Archive S3 Object Lock Write-once logs Audit GuardDuty Security Hub Network Transit GW Egress Firewall Workloads OU SDLC + Production SDLC dev account staging account Production Strict SCPs No public S3 Sandbox OU Dev experimentation Sandbox Accts Cost-limited SCPs No prod peering Suspended OU Deny-all SCP Offboarding All actions denied Awaiting deletion Centralized Logging (Log Archive Account) CloudTrail Org Trail AWS Config (all regions) VPC Flow Logs S3 Access Logs S3 Object Lock (WORM) — 90-day minimum retention — KMS encrypted All accounts ship logs to the Log Archive account — none can delete them
Landing Zone OU hierarchy: accounts are grouped by policy boundary, with centralized write-once logging shared across the organization.

Service Control Policies: Preventive Guardrails

Service Control Policies (SCPs) are JSON-based IAM-syntax policies attached to the root, an OU, or an individual account in AWS Organizations. They define the maximum permissions boundary for everyone in that scope — including the account's own root user. An SCP does not grant permissions; it filters what IAM policies inside the account can allow.

Critical SCP patterns every Landing Zone must implement:

# SCP: Deny leaving the organization or disabling CloudTrail # Attach to Root OU — applies to every account including management { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyLeaveOrg", "Effect": "Deny", "Action": "organizations:LeaveOrganization", "Resource": "*" }, { "Sid": "DenyDisableCloudTrail", "Effect": "Deny", "Action": [ "cloudtrail:DeleteTrail", "cloudtrail:StopLogging", "cloudtrail:UpdateTrail" ], "Resource": "*" }, { "Sid": "DenyDisableGuardDuty", "Effect": "Deny", "Action": [ "guardduty:DeleteDetector", "guardduty:DisassociateFromMasterAccount", "guardduty:StopMonitoringMembers" ], "Resource": "*" } ] }
# SCP: Restrict to approved AWS regions only (Production OU) # Attach to Workloads/Production OU { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyOutsideApprovedRegions", "Effect": "Deny", "NotAction": [ "iam:*", "organizations:*", "route53:*", "budgets:*", "waf:*", "cloudfront:*", "sts:*", "support:*", "trustedadvisor:*" ], "Resource": "*", "Condition": { "StringNotEquals": { "aws:RequestedRegion": [ "us-east-1", "eu-west-1" ] } } }, { "Sid": "DenyPublicS3", "Effect": "Deny", "Action": [ "s3:PutBucketPublicAccessBlock", "s3:DeletePublicAccessBlock" ], "Resource": "*", "Condition": { "StringEquals": { "s3:PublicAccessBlockConfiguration/RestrictPublicBuckets": "false" } } } ] }
SCPs use an implicit deny model combined with an explicit allow on the FullAWSAccess managed SCP that AWS attaches to every new OU. If you remove FullAWSAccess and add only your restrictive SCPs, you must explicitly allow every action you want to permit. Most teams accidentally lock out their own platform team. The safe approach: keep FullAWSAccess attached as a baseline and layer deny-only SCPs on top of it.

AWS Control Tower: Automating the Landing Zone

AWS Control Tower is the managed service that provisions and governs a Landing Zone. It sets up the baseline OU structure, deploys pre-configured accounts (Log Archive and Audit), enables an organization-wide CloudTrail trail, and provides a catalog of guardrails — a mix of SCPs (preventive) and AWS Config rules (detective).

Control Tower's core primitives:

  • Account Factory — a Service Catalog product that provisions a new member account from a template, places it in the correct OU, applies account-level configurations (baseline IAM roles, budget alerts, VPC settings), and enrolls it into all organization-wide services. Account Factory for Terraform (AFT) is the Infrastructure-as-Code version — each account is a terraform apply.
  • Guardrails — pre-built controls categorized as Mandatory (cannot be disabled, e.g., CloudTrail enabled), Strongly Recommended, and Elective. As of 2025, Control Tower ships with 450+ guardrails. Enable the full Strongly Recommended set on day one.
  • Control Tower Dashboard — gives a compliance posture view across all enrolled accounts. Non-compliant resources surface here before they become incidents.
# Account Factory for Terraform (AFT) — account vending module call # Each block provisions one new AWS account with full guardrail enrollment module "team_alpha_prod" { source = "github.com/aws-ia/terraform-aws-control_tower_account_factory" control_tower_parameters = { AccountEmail = "aws+alpha-prod@yourcompany.com" AccountName = "alpha-prod" ManagedOrganizationalUnit = "Workloads/Production" SSOUserEmail = "platform@yourcompany.com" SSOUserFirstName = "Platform" SSOUserLastName = "Team" } # Account customizations applied post-vend account_customizations_name = "production-baseline" account_tags = { Team = "alpha" Environment = "production" CostCenter = "eng-alpha" } } # AFT then triggers account customizations — a CodePipeline that runs # Terraform to apply: VPC baseline, IAM roles, budget alarms, # default security group rules, and Config rule overrides.

Centralized Logging Architecture

Every API call, resource change, and network flow in your organization must land in the Log Archive account in a tamper-evident, immutable store. This is not optional — it is the evidence chain for security incidents, compliance audits, and post-mortems.

The correct logging stack:

  • AWS CloudTrail — Organization Trail: a single trail enabled from the management account that captures management events from all current and future member accounts into the Log Archive S3 bucket. Enable data events for S3 and Lambda selectively (they are high-volume and expensive to capture wholesale).
  • AWS Config — Organization Aggregator: records configuration state and changes for all resource types across all accounts and regions. Feeds into Config Rules for compliance evaluation. The aggregator view in the management or Audit account gives a single-pane view of every resource in the organization.
  • VPC Flow Logs: enabled at the VPC level in each workload account, delivered to the centralized log bucket (or a regional CloudWatch Logs group that is then exported). Use v5 format to capture traffic metadata including TCP flags and packet-level statistics.
  • S3 Object Lock: the log bucket must use COMPLIANCE mode Object Lock with a minimum 90-day retention. In COMPLIANCE mode, no user — including the account root — can delete or shorten the retention period. This provides a tamper-evident audit trail even if an attacker compromises organization admin credentials.
At big-tech scale, logs from a large organization can reach petabytes per year. Use S3 Intelligent-Tiering on the log bucket — logs are accessed heavily in the first 30 days (incident response) and rarely after 90 days (compliance archival). This alone typically cuts long-term log storage costs by 40–60% with zero operational overhead.

Enabling an organization-wide CloudTrail from the management account with Terraform:

# Terraform: Organization CloudTrail shipping to Log Archive account resource "aws_cloudtrail" "org_trail" { name = "org-management-trail" s3_bucket_name = "acme-log-archive-cloudtrail" # bucket in Log Archive account include_global_service_events = true is_multi_region_trail = true is_organization_trail = true # captures all member accounts enable_log_file_validation = true # SHA-256 digest every hour kms_key_id = aws_kms_key.cloudtrail.arn event_selector { read_write_type = "All" include_management_events = true # Selective S3 data events — only the log bucket itself and artifact buckets data_resource { type = "AWS::S3::Object" values = [ "arn:aws:s3:::acme-artifacts/", ] } } insight_selector { insight_type = "ApiCallRateInsight" # anomalous API call rates } tags = { ManagedBy = "platform-terraform" } } # S3 bucket in Log Archive account — Object Lock enforces WORM resource "aws_s3_bucket_object_lock_configuration" "log_lock" { bucket = "acme-log-archive-cloudtrail" rule { default_retention { mode = "COMPLIANCE" days = 90 } } }
Enable CloudTrail log file validation (enable_log_file_validation = true). This generates a SHA-256 digest file every hour that chains each log file. If an attacker deletes or modifies a log file, the digest chain breaks — the AWS CloudTrail Validate Logs CLI command will detect tampering even if the attacker also deleted the digest files (the chain cannot be reconstructed without the private key AWS controls).