Skip to content

CloudFront Static Website

Creates a static website hosted on S3 with CloudFront distribution, SSL certificate, and custom domain.

[!NOTE] This stack might take a long time to both apply and destroy due to the CloudFront distribution. Deployment typically takes around 5 minutes, while destruction can take 5-6 minutes.

[!NOTE] This template has a dependency on the CloudFront data template which creates the S3 buckets used for content and logging.

Architecture

This template creates the CloudFront distribution and associated resources that work with the S3 buckets created by the CloudFront data stack:

  • CloudFront Distribution - CDN with custom domain, SSL, and SPA routing
  • Route53 Record - DNS alias pointing to CloudFront
  • ACM Certificate - SSL certificate for custom domain (us-east-1)
  • IAM Role (optional) - GitHub OIDC role for CI/CD deployments

The S3 buckets (content and logs) are created separately in the Data stack to allow for independent lifecycle management.

Features

  • HTTPS-only with custom domain
  • Client-side routing support (when ClientSideRouting.Enable: true) - 403 errors redirect to 200 index.html (similar to react-cors-spa)
  • Optional URL rewriting (when DirectoryBehavior.AddToAllUrls: true) - adds index.html to directory requests and URLs without extensions, based on AWS CloudFront Functions sample
  • Configurable root and error objects via DirectoryBehavior
  • GitHub Actions deployment permissions (when enabled)

Configuration

This template uses variables defined in the boilerplate configuration. See the Variables section below for the complete list of available options.

Usage

With Boilerplate

  1. Generate the CloudFront data template first (if not already done)
  2. Generate this template with your Name
  3. Update config_override.tf with your AWS account/environment details
  4. Run terraform apply
  5. Upload static files to the S3 bucket created by the data stack
  6. Access your site at https://{Name}.{environment}.oslo.systems

With ok and configuration files

Create the following files in your project directory (e.g., monkey-web):

packages.yml:

Packages:
  - OutputFolder: .
    Ref: main
    Template: cloudfront-static-website
    VarFiles:
      - ../common-config.yml
      - package-config.yml

package-config.yml:

StackName: "web-monkey"
cloudfront-static-website-data.StackName: "web-monkey-data"
Name: "monkey"
IamForCicd:
  Enable: true
  GitHubRepo: golden-path-iac

Then run:

  1. ok pkg install - Terraform files will appear
  2. cd to the data stack directory, apply that with terraform apply
  3. Go back to the main directory (web-monkey) and apply with terraform apply
  4. Upload static files to the S3 bucket created by the data stack
  5. Access your site at https://{Name}.{environment}.oslo.systems

Deployment

Manual Deployment

Upload static files manually to the S3 bucket created by the CloudFront data stack.

Automated Deployment

For automated deployments, use the CloudFront deploy workflow template which:

  • Builds your static site using Docker
  • Syncs files to the S3 bucket
  • Creates CloudFront cache invalidations

When IamForCicd.Enable is true, a GitHub OIDC role is created with permissions to:

  • Upload files to S3 bucket
  • Create CloudFront invalidations
  • Deploy from GitHub Actions workflows

The role can be assumed by GitHub Actions in the specified repository.

Variables

Name Description Type Default Required
IncludeLockFile Include a Terraform lock file. bool false no
Name Name for the CloudFront static website resources string n/a yes
RedirectAllToIndex Make the Cloudfront distribution compatible with client-side routing (e.g., React Router), forwarding all requests to index.html bool false no
RootObject Default object to serve for directory requests string index.html no
ErrorObject Default error page object string 404.html no
AppendIndexToDirectories Append index.html to directory URLs bool false no
DeploymentPipelineV2 Enable the next-generation deployment pipeline. Replaces IamForCicd. map {"Enable": false} no
IamForCicd Enable IAM roles for CI/CD. map {"Enable": false, "GitHubRepo": null} no