Deployment Pipeline
Deployment Pipeline
This page is the developer-facing summary of how code moves from the repo into AWS. Use the Terraform reference pages for the full infrastructure layout:
Workflow
The release flow is:
- Make and test your code changes locally.
- Build the container image for the service you changed.
- Tag the image with an immutable SHA-based tag.
- Push the image to the staging ECR.
- Update the staging Terraform image tag map.
- Run
terraform applyfor staging. - After staging is validated, copy the staging tag map into production, mirror the promoted images into prod ECR, and apply prod.
If you prefer a shorter command path, the repo also provides a thin Makefile wrapper:
make staging-buildmake staging-planmake staging-applymake staging-deploymake prod-promotemake prod-deploy
Those are the normal promotion targets.
Direct production operations are still available when needed:
make prod-buildmake prod-planmake prod-apply
Those targets still call the same build scripts and Terraform commands under the hood, but they are not the default release path.
Build And Tag
From the repository root, use make staging-build to build the staging images with the current git SHA and push them to the staging ECR:
make staging-build TARGETS="api"
The script behind the target:
- logs in to the staging ECR registry when
--pushis set - runs
docker buildx bakeagainstdocker-bake.hcl - writes
infra/envs/staging/image-tags.auto.tfvars.jsonunless--no-tfvarsis used - accepts
--targetso you can build only the image you changed
If you need the direct script invocation, the staging flow is:
python scripts/build_staging_images.py \
--push \
--aws-profile glimpse-staging \
--target api
That writes infra/envs/staging/image-tags.auto.tfvars.json unless --no-tfvars is used.
When you promote to production, make prod-promote copies the staged Terraform tag map and mirrors the promoted SHA tags into the production ECR.
The bake file builds the standard set of images:
tracker-apitracker-frontendtracker-admintracker-services
If you only need one image, pass --target api, --target admin, and so on to the script.
Deploy With Terraform
After pushing the images, the script already updates the staging environment tag map. Apply Terraform to roll the staging image tags out:
terraform -chdir=infra/envs/staging apply -auto-approve
Terraform updates the ECS task definitions to point at the new immutable image tags and rolls the services forward.
Once staging is validated, promote the exact same tag map to production:
make prod-promote
terraform -chdir=infra/envs/prod apply -auto-approve
This keeps production on the same commit-tested image set as staging without rebuilding.
First Deploy
On a brand-new environment, start with the bootstrap tag so Terraform can create valid task definitions before any real images exist in ECR.
Use sha-bootstrap for the initial image_tags map, run the first terraform apply, then build and push real images and re-apply with the final SHA tags.
Rollback
To roll back, change the relevant image tag in image-tags.auto.tfvars.json to a previous immutable tag and re-apply Terraform in the target environment.
Because ECR tags are immutable in this project, the old image remains available for rollbacks.
Versioning & Releases
The repo carries one version (VERSION at the repo root, currently semver
X.Y.Z) across the backend, both Svelte apps, and services together, since
they already build and deploy as one set of images. CHANGELOG.md records
one entry per version, including the exact git commit it was built from.
A version is only cut when preparing a prod push, not on every merge to
main. Cut it first, before staging-build, so the release commit itself is
what gets SHA-tagged and tested in staging - prod-promote then mirrors that
exact tested image into prod rather than rebuilding, same as it always has.
make release # bumps VERSION, adds a CHANGELOG.md entry, commits, tags v X.Y.Z
git push && git push origin vX.Y.Z # after reviewing the commit/tag
make staging-build RELEASE_TAG="v$(cat VERSION)"
make staging-apply
# validate in staging
make prod-promote RELEASE_TAG="v$(cat VERSION)"
make prod-apply
make release (scripts/cut_release.py) looks at commits since the last
vX.Y.Z tag and infers the bump:
- major - only with an explicit
make release RELEASE_ARGS="--bump major", never inferred - minor - any
[feat]commit since the last release - patch - everything else (
[fix],[docs],[chore], ...)
RELEASE_TAG is a separate, opt-in Makefile variable from the always-on
immutable sha-<commit> tag - passing it to staging-build/prod-build/
prod-promote pushes/mirrors a second tag (e.g. v2.1.0) alongside the SHA
tag on the same image, purely for human/changelog traceability. Terraform
still pins deployments by the SHA tag either way.