Steps to take the generated static tree live on pixieengine.com. Plan: a greenfield AWS CDK stack (
infra/,PixieStaticStack) stands up a new private S3 bucket + new CloudFront distribution + edge function. The legacy distributionE3BKYYG8EH9O0Kis never touched. Cutover = move thepixieengine.comDNS alias to the new distribution; rollback = move it back. Companion toarchitecture.md; the canonical infra-as-code runbook is../infra/README.md.(Historical note: an earlier draft of this doc repointed
E3BKYYG8EH9O0K's origin in place. That approach is superseded by the greenfield stack below — it's safer, fully reversible via DNS, and keeps the live distribution untouched until verification passes.)
- New distribution: a fresh CloudFront distribution (separate from
E3BKYYG8EH9O0K).index.htmlroot object;403/404 → /410/index.htmlserved as 404 (CloudFront can't emit a 410 in custom-error responses); rewrite function on viewer-request. - New bucket:
pixieengine-static— private, CloudFront OAC only,RETAINremoval policy. - Edge function:
pixieengine-rewrite(infra/functions/rewrite.js; id/slug rewrite,?tagged=→/tags/301, dir→index). Unit-tested vianpm testininfra/. - Custom domain (cutover only,
-c withDomain=true): ACM cert (DNS-validated in zoneZPF3QICRGSLCF) +pixieengine.comalias + Route 53 A/AAAA → new dist. - Deploy IAM user:
pixieengine-deploy(scoped — policy inaws-inventory.md): rw on the bucket +cloudfront:CreateInvalidation. The stack grants it read/write onpixieengine-static.
The initial upload used a hand-made staging bucket
pixieengine-com-site(256,530 objects), server-side-copied intopixieengine-static. That bucket was deleted 2026-06-02; deploys now sync directly from../static-site/public(below).
cdk deployneeds admin creds → run from AWS CloudShell (uses the console admin/root identity, no local keys).cdk synth/diff,npm test, andaws s3 syncrun fine locally with the scoped profiles (pixieengine-deployrw,pixieengine-auditread-only).infra/is self-contained (includesfunctions/rewrite.js). Get it into CloudShell viagit push+clone, or upload a zip.
cd ~/apps/pixieengine.com/infra
npm install
npm test # rewrite-function unit tests (16 assertions)
npx cdk synth # confirms the stack compiles to a valid templateIn CloudShell:
cd infra && npm install
npx cdk bootstrap aws://186123361267/us-east-1 # once per account/region
npx cdk deploy # creates bucket + dist + function; alias NOT attachedNote the DistributionId and DistributionDomain (dXXXX.cloudfront.net) outputs.
Content is not managed by CDK (it's a deploy step). Sync the generated tree from local:
aws s3 sync ../static-site/public s3://pixieengine-static --delete --profile pixieengine-deploy
aws cloudfront create-invalidation --distribution-id <DistributionId> --paths "/*"https://dXXXX.cloudfront.net/→ editor shell (200);/sprites/→ gallery;/sprites/page/100/→ logarithmic pager./sprites/257680-ugly-killman-donkey-ass→ sprite page (slug variant 200)./sprites?tagged=mario→ 301 →/tags/mario/.- A missing id (e.g.
/sprites/999999999) → 404 (the/410/index.htmlgone page). /sitemap.xml→ 200.- A sprite with a replay → ▶ Watch replay plays in the editor.
- A tune → ▶ Play in Composer loads in the composer.
A CloudFront alias can live on only one distribution. So, only after verification passes:
- Remove the
pixieengine.comalias (CNAME) from the legacy distE3BKYYG8EH9O0K(console). - Add it to the new dist + create cert + DNS:
(ACM DNS validation auto-creates a CNAME in the zone; the first deploy waits for it.)
npx cdk deploy -c withDomain=true # ACM cert, alias, Route 53 A/AAAA -> new dist - Verify
https://pixieengine.com/(rerun the section-D checklist on the apex domain).
Re-point the pixieengine.com Route 53 alias back to the legacy dist E3BKYYG8EH9O0K (or re-add
the alias there). Nothing in the legacy distribution was modified, so rollback is pure DNS.
aws s3 sync ../static-site/public s3://pixieengine-static --delete --profile pixieengine-deploy
aws cloudfront create-invalidation --distribution-id <DistributionId> --paths "/*" --profile pixieengine-deployIncremental regen (enriched titles, etc.) → re-generate → s3 sync → invalidate just the changed
paths. Full tree is ~256k objects.
- Content-types are inferred from extensions (
.html→text/html,.css→text/css,.xml→application/xml). - After launch: delete the temporary
pixieengine-audituser. (The staging bucketpixieengine-com-sitewas deleted 2026-06-02.)