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, rolling back 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.jsonUse 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