AWS

CDK bootstrap for public S3 asset buckets

How to quickly setup your distribution buckets in all AWS regions

Photo by Pexels

Introduction

Say you build a CDK construct and want people to deploy it as a plain CloudFormation template, without installing CDK. That means hosting the synthesized template plus its assets - the custom-resource Lambda code and so on - in public S3 buckets, in every region your users deploy to.

The challenge

A few things have to line up:

  • How do you make the S3 buckets publicly readable, on purpose and safely?
  • Where do the assets live, and in which regions?
  • How does your GitHub Actions release workflow push into them without long-lived keys?

The solution

This construct sets up that bootstrap once, split into two stacks:

  • DistributionStack - one release bucket for the main template, plus a scoped GitHub OIDC upload role per repository (via aws-cdk-github-oidc, 1-hour sessions, grantPut limited to an object-key prefix). No static credentials in CI.
  • AssetsBucketStack - one public-read asset bucket per region, deployed across the nine SES-capable regions (us-east-1, eu-west-1, us-west-2, eu-central-1, and so on).

dev and prod behave differently on purpose: dev buckets get a 14-day lifecycle expiry and RemovalPolicy.DESTROY, prod buckets RETAIN. You deploy the release stack once, then loop the asset stack over each region.

See also the related deep technical post here.

Conclusion

Because other folks might have the same challenge, I published the module on GitHub: s3-cdk-assets-bootstrap

Engineers reviewing cloud architecture

Track record

Outcomes that hold up in production

Measured results from real engagements - faster releases, lower bills, and platforms that stay healthy under load.

Production AWS workloads shipped
25+
Typical deployment frequency
10x / day
Uptime maintained across clients
99.999%
Average cloud cost reduced
23%

Ready to ship faster on AWS?

Tell us what you are building. We will map the fastest safe path to production and the platform to keep it there.