The AWS Control Tower team has been shipping features at a blistering pace this year. Two stand-outs landed in May 2025:
- Centralized “Enabled Controls” view in the console, a one-stop dashboard that lists every preventive, detective, and proactive control you’ve switched on across all OUs and accounts. Amazon Web Services, Inc.
- 233 new AWS Config-backed controls plus automatic baseline-drift reporting to surface deviations from best practice as they happen. docs.aws.amazon.com
If you’re still on Landing-Zone 2.x (or early 3.x), now is the perfect moment to upgrade and start harvesting these capabilities programmatically. This article walks you through:
- A fast, production-safe upgrade path to Landing Zone 3.3
- A lightweight serverless pattern that streams the new Enabled Controls data into your own compliance dashboard
1 | Why bother upgrading?
AWS Control Tower already gives you prescriptive multi-account governance out of the box: foundational OUs, centralised logging & audit accounts, guardrails, and account vending. docs.aws.amazon.com
Version 3.3 raises the bar:
Upgrade highlight | What it means in the real world |
---|---|
Enabled Controls view & API | Instantly see which controls are missing from which OU, no more hunting OU-by-OU |
Baseline drift detection | Get notified when someone disables CloudTrail or deletes an S3 bucket policy the guardrail requires |
Region schemas | Fine-grained control over which Regions are governed, now including AP-South-East-6 (Bangkok) and MX-Central-1 (Querétaro) |
233 new Config controls | Deeper coverage for networking, encryption, and IAM edge cases |
2 | Pre-flight checklist
Task | Rationale |
---|---|
Audit SCP quotas | OUs can have max 5 SCPs; CT may attach up to 3. Consolidate overlapping SCPs first. |
Disable “Requester Pays” on the Log-Archive S3 bucket | Required or the update will fail. docs.aws.amazon.com |
Tag temporary exclusions | Note any controls you had to suppress — you’ll re-evaluate them post-upgrade. |
Notify account owners | Updating shared accounts briefly locks their CloudFormation StackSets; warn dev teams about a 30–40 min freeze window. |
3 | Upgrade in three commands (or three clicks)
Console path
Navigate to Control Tower → Landing-zone settings → Update and follow the wizard. The backend update plus shared-account StackSets usually finishes within 40 minutes. docs.aws.amazon.com
API / CLI path
Handy when you’re automating in a pipeline:
aws controltower update-landing-zone \
--landing-zone-version 3.3 \
--landing-zone-identifier arn:aws:controltower:eu-west-1:123456789012:landingzone/LZID \
--manifest file://LandingZoneManifest.json
You can pin a specific manifest with Region allow-lists or central-logging tweaks. docs.aws.amazon.com
Re-register your OUs after the landing-zone core update. In 3.x this is as simple as selecting each OU and hitting Re-register; it cascades new StackSets to every member account. docs.aws.amazon.com
4 | Harvesting the Enabled Controls API
Once upgraded, you can query the same data that powers the new console page via the controltower:GetEnabledControls
endpoint (boto3: list_enabled_controls
). The pattern below dumps the results nightly to S3, then refreshes a QuickSight dashboard.
Architecture at a glance

No QuickSight? You can use a simple Athena → CSV export emailed to auditors.
Sample Lambda (Python 3.12)
import boto3, json, os, gzip, datetime as dt
ct = boto3.client("controltower")
def handler(event, context):
paginator = ct.get_paginator("list_enabled_controls")
rows = []
for page in paginator.paginate():
for ctrl in page["EnabledControls"]:
rows.append(ctrl) # contains controlIdentifier, targetArn, etc.
ts = dt.datetime.utcnow().strftime("%Y-%m-%dT%H-%M-%SZ")
key = f"{ts}.json.gz"
body = gzip.compress(json.dumps(rows, indent=2).encode())
s3 = boto3.client("s3")
s3.put_object(
Bucket=os.environ["BUCKET"],
Key=key,
Body=body,
ContentType="application/json",
ContentEncoding="gzip",
)
return {"saved": key, "count": len(rows)}
Best practices
- Store snapshots daily; Athena can diff yesterday vs today to highlight newly disabled controls.
- Add a second EventBridge rule for
ControlTower Drift Detected
events to trigger on change for faster response. - Enforce “deny delete” S3 bucket policy so historical evidence can’t be tampered with.
5 | Cost & Ops tips
- Lambda runtime + Athena scans ≈ a few USD/month unless you have thousands of accounts. Compress snapshots and partition S3 by date to keep Athena bills tiny.
- QuickSight (Standard) is $5 per author/mo + $0.30 per 1 k queries for readers; or export to Google Sheets free tier.
- Keep the update cadence: AWS drops minor landing-zone versions roughly quarterly; schedule a semi-annual review to stay current.
6 | Key takeaways
- Landing-Zone 3.3 gives you a richer guardrail catalogue and baseline-drift detection out of the box.
- The new Enabled Controls API finally lets you query control coverage programmatically — no more spreadsheet gymnastics.
- A minimalist Lambda → S3 → Athena pipeline surfaces coverage gaps and change history with near-zero maintenance overhead.
Ready to try it in your own org? Fork the Lambda snippet, point it at a dev OU, and watch the insights roll in. As always, I’d love feedback: hit me up on LinkedIn or drop a comment below if you have questions or war stories from your own upgrade.
Happy automating — and may your guardrails always be green!