Hosting a static site on AWS with CDK

This very site runs on a small, boring, reliable stack: a private S3 bucket served through CloudFront, with DNS on Route 53 — all defined in the AWS CDK.

The shape of it

Route 53 (A/AAAA alias)  ->  CloudFront (HTTPS, ACM cert)  ->  S3 (private, OAC)

The bucket is not public. CloudFront reaches it through Origin Access Control (OAC), and a bucket policy lets only that one distribution read it.

The core construct

const bucket = new s3.Bucket(this, 'SiteBucket', {
  blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
  encryption: s3.BucketEncryption.S3_MANAGED,
  enforceSSL: true,
});

const distribution = new cloudfront.Distribution(this, 'SiteDistribution', {
  defaultRootObject: 'index.html',
  defaultBehavior: {
    origin: origins.S3BucketOrigin.withOriginAccessControl(bucket),
    viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
  },
});

That withOriginAccessControl call is the whole trick: it wires the private bucket to CloudFront and writes the scoped bucket policy for you.

Why bother with IaC

Because next time I can recreate the entire thing with one command, and the diff of any change is reviewable before it ships. Boring infrastructure is a feature.

← Back to all posts