---
title: "AWS Landing Zone"
description: "A single-account AWS landing zone - a two-AZ VPC, KMS key, VPC flow logs, deployer and read-only IAM roles, and an encrypted CloudTrail audit trail that downstream Pulumi projects build on."
url: "https://www.pulumi.com/dev/examples/aws-ts-landing-zone/"
image: "https://www.pulumi.com/assets/og/dev/examples/aws-ts-landing-zone.png"
---

# AWS Landing Zone

A single-account AWS landing zone - a two-AZ VPC, KMS key, VPC flow logs, deployer and read-only IAM roles, and an encrypted CloudTrail audit trail that downstream Pulumi projects build on.

- Source on GitHub: https://github.com/pulumi/examples/tree/master/aws-ts-landing-zone
- Deploy with Pulumi: https://app.pulumi.com/new?template=https%3A%2F%2Fgithub.com%2Fpulumi%2Fexamples%2Ftree%2Fmaster%2Faws-ts-landing-zone

## Get started with this example

This example lives in the [pulumi/examples](https://github.com/pulumi/examples/tree/master/aws-ts-landing-zone) repo. Pull down just this directory to follow along:

```bash
git clone --filter=blob:none --sparse https://github.com/pulumi/examples pulumi-examples
git -C pulumi-examples sparse-checkout set aws-ts-landing-zone
cd pulumi-examples/aws-ts-landing-zone
```

The foundational, shared resources a single AWS account needs before any workload lands on top of it. Deploy this once per account, then have every downstream Pulumi project consume its outputs (via a [StackReference](https://www.pulumi.com/docs/concepts/stack/#stackreferences)) instead of re-creating the same plumbing.

> **Note:** This is an illustrative example of how you _might_ model a landing zone in Pulumi, not a production-ready one. A real landing zone would typically add guardrails this example leaves out for brevity — Service Control Policies, AWS Config rules, GuardDuty/Security Hub, cross-account centralized logging, and IAM roles scoped to specific tasks rather than the broad `PowerUserAccess`/`ReadOnlyAccess` used here.

The `LandingZone` component provisions:

- A **VPC** across three availability zones, with public and private subnets, an internet gateway, and per-AZ NAT gateways (built with the [`awsx.ec2.Vpc`](https://www.pulumi.com/registry/packages/awsx/api-docs/ec2/vpc/) component).
- A **KMS customer-managed key** (with rotation) and a key policy that lets CloudWatch Logs and CloudTrail use it.
- **VPC flow logs** delivered to an encrypted CloudWatch log group.
- **Deployer** (`PowerUserAccess`) and **read-only** (`ReadOnlyAccess`) IAM roles that a trusted principal can assume.
- An encrypted, multi-region **CloudTrail** audit trail writing to a lifecycle-managed S3 bucket.

The companion example [`aws-ts-serverless-react-postgres`](https://github.com/pulumi/examples/tree/master/aws-ts-serverless-react-postgres) consumes this stack's `networkId`, `privateSubnetIds`, and `secretsStore` outputs.

## Prerequisites

1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/)
1. [Configure your AWS credentials](https://www.pulumi.com/docs/intro/cloud-providers/aws/setup/)
1. [Install Node.js](https://www.pulumi.com/docs/intro/languages/javascript/)

## Deploying and running the program

1.  Create a new stack:

    ```bash
    pulumi stack init dev
    ```

1.  Set the AWS region:

    ```bash
    pulumi config set aws:region us-west-2
    ```

    Optionally override the VPC CIDR block or the principal trusted to assume the roles:

    ```bash
    pulumi config set cidrBlock 10.10.0.0/16
    pulumi config set trustedPrincipalArn arn:aws:iam::123456789012:root
    ```

1.  Install dependencies:

    ```bash
    npm install
    ```

1.  Run `pulumi up` to preview and deploy:

    ```bash
    pulumi up
    ```

1.  Inspect the outputs downstream stacks will reference:

    ```bash
    pulumi stack output
    ```

    ```
    Current stack outputs (9):
        OUTPUT                  VALUE
        auditBucket             platform-audit-***
        dataEncryptionKeyAlias  alias/platform-landing-zone
        dataEncryptionKeyArn    arn:aws:kms:us-west-2:***
        deployerRoleArn         arn:aws:iam::***:role/platform-deployer
        networkId               vpc-***
        privateSubnetIds        ["subnet-***","subnet-***","subnet-***"]
        publicSubnetIds         ["subnet-***","subnet-***","subnet-***"]
        readOnlyRoleArn         arn:aws:iam::***:role/platform-readonly
        secretsStore            platform/
    ```

## Clean up

To tear down the resources, run:

```bash
pulumi destroy
pulumi stack rm
```

## Summary

In this example you deployed a reusable AWS landing zone: network, encryption, audit logging, and workload identities that every project in the account can share. Reference its outputs from your application stacks with a `StackReference` to keep foundational infrastructure in one place.
