Level-Up Your Landing Zone: Upgrading AWS Control Tower to v3.3 & Using the New Enabled Controls API for Continuous Gap Analysis

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:

  1. A fast, production-safe upgrade path to Landing Zone 3.3
  2. 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 highlightWhat it means in the real world
Enabled Controls view & APIInstantly see which controls are missing from which OU, no more hunting OU-by-OU
Baseline drift detectionGet notified when someone disables CloudTrail or deletes an S3 bucket policy the guardrail requires
Region schemasFine-grained control over which Regions are governed, now including AP-South-East-6 (Bangkok) and MX-Central-1 (Querétaro)
233 new Config controlsDeeper coverage for networking, encryption, and IAM edge cases

2 | Pre-flight checklist

TaskRationale
Audit SCP quotasOUs can have max 5 SCPs; CT may attach up to 3. Consolidate overlapping SCPs first.
Disable “Requester Pays” on the Log-Archive S3 bucketRequired or the update will fail. docs.aws.amazon.com
Tag temporary exclusionsNote any controls you had to suppress — you’ll re-evaluate them post-upgrade.
Notify account ownersUpdating 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!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.