Skip to content

duskydots/terraform-cloudfront-single-page-application

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

terraform-cloudfront-single-page-application

Minimal Terraform demo: host a Single Page App (SPA) in S3, serve via CloudFront, keep S3 private.

What this deploys

  • S3 bucket for app assets
  • S3 public access fully blocked
  • S3 default encryption (SSE-S3)
  • S3 versioning enabled
  • CloudFront distribution in front of S3
  • CloudFront Origin Access Control (OAC)
  • Bucket policy allowing s3:GetObject only from this CloudFront distribution
  • Bucket policy denying non-TLS S3 requests
  • SPA fallback (403 -> /index.html)
  • CloudFront managed cache policy + managed security headers policy

Why this works

  • App files are not public in S3.
  • Users hit CloudFront only.
  • HTTP requests are redirected to HTTPS at CloudFront.
  • Deep links and page refreshes work for SPAs because unknown paths return index.html.

Architecture

Browser -> CloudFront (HTTPS, cache, security headers) -> S3 (private via OAC)

Prerequisites

  • Terraform ~> 1
  • AWS provider ~> 6 (handled by terraform init)
  • AWS credentials configured (aws configure, SSO, env vars, etc.)
  • IAM permissions for S3, CloudFront, IAM policy documents

Inputs

  • bucket_name (required)
  • region (optional, default us-east-1)

Quick start

  1. Initialize:
terraform init
  1. Apply:
terraform apply -var="bucket_name=zxcvmbn123u8oakdfa"
  1. Upload your SPA files:
aws s3 cp . s3://zxcvmbn123u8oakdfa --recursive
  1. Get URL:
terraform output cloudfront_domain_name

Open https://<cloudfront_domain_name>.

Updating app files

Upload new files again:

aws s3 cp . s3://zxcvmbn123u8oakdfa --recursive

Optionally invalidate cache:

aws cloudfront create-invalidation --distribution-id <DIST_ID> --paths "/*"

Destroy

terraform destroy -var="bucket_name=zxcvmbn123u8oakdfa"

Notes

  • No custom domain/ACM in this demo; it uses the default CloudFront domain and certificate.
  • If you need custom domain aliases or stricter TLS policy control, add ACM in us-east-1 and Route53 records.

Invalidate cache:

aws cloudfront create-invalidation --distribution-id <DIST_ID> --paths "/*"

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages