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.
This example lives in the pulumi/examples repository. Check out just this directory to use it:
git clone --filter=blob:none --sparse https://github.com/pulumi/examples pulumi-examplesgit -C pulumi-examples sparse-checkout set aws-ts-landing-zonecd pulumi-examples/aws-ts-landing-zoneThe 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) 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/ReadOnlyAccessused 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.Vpccomponent). - 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 consumes this stack’s networkId, privateSubnetIds, and secretsStore outputs.
Prerequisites#
Deploying and running the program#
-
Create a new stack:
Terminal window pulumi stack init dev -
Set the AWS region:
Terminal window pulumi config set aws:region us-west-2Optionally override the VPC CIDR block or the principal trusted to assume the roles:
Terminal window pulumi config set cidrBlock 10.10.0.0/16pulumi config set trustedPrincipalArn arn:aws:iam::123456789012:root -
Install dependencies:
Terminal window npm install -
Run
pulumi upto preview and deploy:Terminal window pulumi up -
Inspect the outputs downstream stacks will reference:
Terminal window pulumi stack outputCurrent stack outputs (9):OUTPUT VALUEauditBucket platform-audit-***dataEncryptionKeyAlias alias/platform-landing-zonedataEncryptionKeyArn arn:aws:kms:us-west-2:***deployerRoleArn arn:aws:iam::***:role/platform-deployernetworkId vpc-***privateSubnetIds ["subnet-***","subnet-***","subnet-***"]publicSubnetIds ["subnet-***","subnet-***","subnet-***"]readOnlyRoleArn arn:aws:iam::***:role/platform-readonlysecretsStore platform/
Clean up#
To tear down the resources, run:
pulumi destroypulumi stack rmSummary#
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.