Deploy a Static Website with S3 and CloudFront CDN

By Pulumi Team
Published
Updated

The Challenge

You need to host a static website with fast global delivery, HTTPS encryption, and custom domain support. This pattern is essential for blogs, marketing sites, documentation portals, single-page applications, or any frontend that compiles to static assets.

What You'll Build

  • S3 bucket configured for static website hosting
  • CloudFront CDN for global content delivery
  • SSL/TLS certificate for HTTPS
  • Custom domain support with Route53
  • Optimized caching and error handling
  • Access logs for monitoring

Neo Try This Prompt in Pulumi Neo

Run this prompt in Neo to deploy your infrastructure, or edit it to customize.

Best For

Use this prompt when you need to host a static website (React app, Vue.js, documentation site, blog, marketing page) with production-grade features like HTTPS, custom domain, and global CDN. Ideal for any frontend that compiles to static files and needs fast load times worldwide.

Architecture Overview

This architecture follows the standard AWS pattern for serving static content at scale. An S3 bucket stores your website files, a CloudFront distribution caches and serves them from edge locations around the world, and ACM provides a free SSL/TLS certificate so everything is served over HTTPS. Route53 ties it together by routing your custom domain to the CloudFront distribution.

The key design decision is using CloudFront’s origin access controls to keep the S3 bucket private. Rather than making the bucket publicly accessible (which introduces security risks and bypasses CDN caching), only CloudFront can read from the bucket. Users always go through the CDN, which means consistent caching behavior, HTTPS enforcement, and a single access point to monitor.

This pattern works well for any site that compiles to static files. The trade-off is that content updates require a CloudFront cache invalidation to propagate immediately, though you can configure cache TTLs to balance freshness against performance. For most static sites, this is a non-issue since deployments are infrequent relative to request volume.

S3 Origin Bucket

The S3 bucket holds your HTML, CSS, JavaScript, images, and other static assets. It is configured with an index document (typically index.html) and a custom error document for 404 pages. The bucket itself is not publicly accessible; CloudFront accesses it through origin access controls.

CloudFront Distribution

The CloudFront distribution is the public-facing layer. It caches content at edge locations globally, terminates TLS using your ACM certificate, and routes requests back to S3 when the cache misses. Custom error responses let you return friendly error pages instead of raw S3 errors.

ACM Certificate and Route53

ACM provisions and automatically renews an SSL/TLS certificate for your domain. Route53 alias records point your domain (and optionally a www subdomain) to the CloudFront distribution, enabling clean URLs without exposing CloudFront’s default domain name.

Common Customizations

  • Add a www redirect: Extend the prompt to include a redirect from www.example.com to the apex domain (or vice versa) using a second CloudFront distribution or S3 redirect rules.
  • Enable CloudFront Functions: Add edge-side logic for URL rewrites, header manipulation, or A/B testing by requesting CloudFront Functions or Lambda@Edge associations.
  • Adjust cache behavior: Request specific cache TTLs or cache policies if your site updates frequently and you want to minimize invalidation overhead.
  • Add WAF protection: Ask for an AWS WAF web ACL attached to the CloudFront distribution to protect against common web exploits or rate-limit abusive traffic.