Implementing Rollback in SSG with Cloudfront
Since entire site is pre-rendered, difference in layout between mobile/desktop causes higher CLS.
Part of Series: Statically Generated Sites
Table of Contents
The Problem
SSG Generates all the pages at build time, and hence with increasing pages, the build time increases. During an incident, re-generating the entire site after a fix will take time. Since the SSG has all the static content already, rollbacking to a previous build is often better while you resolve the incident.
Solution
Keep the previous builds
In your S3 bucket, while pushing the changes for a new build, instead of replacing the old files, we can just push into a new directory with buildNumber.
S3 Bucket├── build_001│ ├── index.html│ ├── ...├── build_002│ ├── ...├── build_003│ ├── ...└── build_004 ├── ...
Configure a custom origin header in CF
Add a header in CDN’s origin configuration. This is always updated with the new release post syncing all the files to S3
To add buildVersion
, navigate to the CF distribution and Select Origins -> Select Origin -> Edit -> Origin Custom Headers

Make a given version live (forward / rollback)
aws configure set aws_access_key_id "$AWS_ACCESS_KEY_ID"aws configure set aws_secret_access_key "$AWS_SECRET_ACCESS_KEY"aws configure set region "$AWS_DEFAULT_REGION"aws cloudfront get-distribution --id $AWS_CF_DISTRIBUTION_ID > cf-config.jsonEtag=$(cat cf-config.json | jq '.ETag' | tr -d \")aws cloudfront get-distribution-config --id $AWS_CF_DISTRIBUTION_ID --query 'DistributionConfig' --output json > dist-config.jsoncat dist-config.json | jq --arg newBuildVersion ${NEW_BUILD_NUMBER} '(.Origins.Items[].CustomHeaders.Items[] | select(.HeaderName == "buildVersion").HeaderValue) |= $newBuildVersion' > dist-config2.jsonaws cloudfront update-distribution --id $AWS_CF_DISTRIBUTION_ID --distribution-config "file://dist-config2.json" --if-match "$Etag" > /dev/nullaws cloudfront wait distribution-deployed --id $AWS_CF_DISTRIBUTION_IDaws cloudfront create-invalidation --distribution-id $AWS_CF_DISTRIBUTION_ID --paths "/*"rm -f dist-config.json dist-config2.json cf-config.json
Use lambda@edge to add prefix in request URI
The lambda@edge will receive this buildNumber header, which it can use to prefix the request URI and hence serving the right file