Skip to main content

Command Palette

Search for a command to run...

Building a Multi-Account Zero-Trust Governance Architecture in AWS Using Terraform, SCPs, and CloudTrail

Updated
6 min read
S
Cyber Security Engineer skilled in AWS, Palo alto, GRC and Healthcare Management

Introduction

Most AWS “security projects” stop at deploying a few services and calling it secure.

Real cloud governance engineering is different.

The difficult part is not provisioning infrastructure. The difficult part is enforcing preventive controls, limiting blast radius, centralising audit visibility, handling SCP inheritance boundaries, and dealing with the operational realities of AWS Organisations and Terraform reconciliation.

In this project, I built a Terraform-managed AWS governance architecture implementing:

  • AWS Organizations

  • Nested Organisational Units (OUs)

  • Service Control Policies (SCPs)

  • Centralised CloudTrail logging

  • Encrypted audit storage

  • Region restriction governance

  • CloudTrail tamper protection

  • Terraform automation

  • Failure simulation and validation testing

The objective was not only to deploy infrastructure, but to validate whether preventive governance controls actually worked under real operational conditions.

Architecture Overview

The AWS Organisations hierarchy was designed to separate governance domains from workload domains.

Root
 ├── Security
 │    ├── Audit
 │    └── LogArchive
 │
 └── Workloads
      ├── Prod
      └── Dev

This structure models a simplified enterprise landing-zone style architecture where:

  • Security OUs isolate governance functions

  • Workload OUs isolate application environments

  • SCP inheritance can be applied hierarchically

  • Blast radius can be reduced through organisational segmentation

Why Zero-Trust Governance Matters

In many AWS environments, the management account becomes a high-risk trust anchor with broad administrative privileges.

Without governance controls:

  • CloudTrail logging can be disabled

  • Resources can be deployed in unauthorised regions

  • Security visibility can be bypassed

  • Blast radius becomes uncontrolled

The objective of this lab was to implement preventive governance mechanisms instead of relying only on detective monitoring.

Deploying AWS Organisations Using Terraform

The AWS Organisation and OU hierarchy were deployed entirely through Terraform.

Organization Resource resource "aws_organizations_organization" "org" { feature_set = "ALL"

lifecycle { ignore_changes = [ enabled_policy_types ] } }

The ignore_changes lifecycle block became necessary because AWS Organisations policy-type propagation introduced Terraform reconciliation drift issues during repeated apply operations.

Organizational Units

resource "aws_organizations_organizational_unit" "security" { name = "Security" parent_id = aws_organizations_organization.org.roots[0].id }

resource "aws_organizations_organizational_unit" "workloads" { name = "Workloads" parent_id = aws_organizations_organization.org.roots[0].id }

Nested child OUs were then created under both governance domains.

Implementing Service Control Policies (SCPs)

Two primary preventive governance controls were implemented:

  1. CloudTrail tamper protection

  2. Region restriction governance

SCP 1 — CloudTrail Tamper Protection

The first SCP prevented users from disabling or deleting CloudTrail logging.

Policy Definition

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyCloudTrailTampering",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:StopLogging",
        "cloudtrail:DeleteTrail"
      ],
      "Resource": "*"
    }
  ]
}

Initial SCP Inheritance Failure

Initially, the SCP was attached only to the Workloads OU.

Testing was performed from the AWS management account located directly under the organisation root.

The SCP did not apply.

This exposed an important AWS Organisations inheritance nuance:

SCP inheritance only applies downward from the attachment point.

The management account remained unrestricted until the SCP was attached directly to the organisation's root level.

Initial SCP attachment at the Workloads OU level

Centralised CloudTrail Logging

A centralised audit logging pipeline was created using:

  • Organisation-wide CloudTrail

  • Encrypted S3 storage

  • Versioning

  • Public access blocking

Terraform Configuration

resource "aws_cloudtrail" "org_trail" { name = "OrganizationTrail" s3_bucket_name = aws_s3_bucket.cloudtrail_logs.id include_global_service_events = true is_multi_region_trail = true enable_logging = true }

Securing the Audit Bucket

The centralised CloudTrail bucket is implemented:

  • SSE-S3 encryption

  • S3 versioning

  • Public access blocking

This ensured:

  • encrypted audit retention

  • accidental deletion resistance

  • public exposure prevention

CloudTrail Bucket Policy Failure

CloudTrail trail creation initially failed with the following error:

InsufficientS3BucketPolicyException

CloudTrail requires explicit bucket permissions allowing:

  • ACL validation

  • log delivery operations

A dedicated bucket policy had to be added before the trial creation succeeded.

This highlighted an operational detail frequently omitted in simplified tutorials.

Validating Preventive Governance Controls

The environment was then tested using AWS CLI failure simulations.

The goal was to verify whether preventive governance controls actually blocked unauthorised operations.

CloudTrail Tampering Simulation

The following command attempted to disable CloudTrail logging:

aws cloudtrail stop-logging --name OrganizationTrail --region ap-south-1

After SCP attachment at the organization root level, the request returned:

AccessDenied

This validated:

  • SCP enforcement

  • centralized governance

  • preventive security controls

  • policy inheritance behavior

CloudTrail Audit Validation

The denied API call was then verified inside CloudTrail Event History.

This confirmed:

  • attempted tampering

  • API identity tracking

  • centralized audit visibility

  • forensic event retention

AWS Service Architecture Nuance

Testing revealed that regional SCP enforcement behaves differently depending on service architecture.

For example:

  • EC2 APIs behaved as expected

  • S3 APIs demonstrated globally scoped behavior nuances

This highlighted an important governance consideration:

Not all AWS services behave consistently under region-based SCP conditions.

Terraform Drift and AWS Organisations Reconciliation Issues

AWS Organisations introduced several operational edge cases during Terraform reconciliation.

One recurring issue involved:

SERVICE_CONTROL_POLICY disable: couldn't find resource

This occurred because AWS Organisations policy-type propagation is eventually consistent and not strongly transactional.

Terraform repeatedly attempted to reconcile the organisation policy state during apply operations.

This required the following workaround:

lifecycle { ignore_changes = [ enabled_policy_types ] }

This became one of the most important operational lessons during the implementation.

Key Engineering Takeaways

This project highlighted several real-world governance engineering realities:

  • AWS Organisations is eventually consistent

  • SCP inheritance boundaries matter

  • Management accounts require special governance consideration

  • CloudTrail requires explicit S3 permissions

  • Governance infrastructure is operationally persistent

  • Terraform reconciliation against AWS Organisations can drift

  • Versioned audit buckets complicate destroy workflows

  • Preventive controls must be validated through failure simulation

Conclusion

This project evolved far beyond a simple Terraform deployment exercise.

The most valuable outcomes came from:

  • governance edge cases

  • SCP inheritance debugging

  • CloudTrail permission failures

  • Terraform reconciliation drift

  • operational teardown behaviour

Those are the same categories of issues encountered in real cloud platform engineering environments.

Building governance controls is relatively easy.

Validating, troubleshooting, and operationalising them is where the actual engineering begins.

More from this blog

Friday aws Security Projects

8 posts

A weekly hands-on cybersecurity publication featuring real-world security projects with labs, scripts, and evidence across cloud, network, and system security.