Skip to content

Deploy Workflows

All deploys and infrastructure changes run as GitHub Actions in infra-volare › Actions. For the step-by-step “I merged a PR, how do I ship it?” guide, read Deployment first; this page is the reference behind it.

I want to… Workflow
Ship a new app version (backend and/or frontend) Deploy Infrastructure
Ship a new app version, changing only the servers Fast-lane ASG Deploy
Apply a changed .env in SSM, or move servers to a new AMI Instance Refresh ASGs
Build a new server image Packer Build
Change alert rules merge to main (Monitoring applies it)
Update Hermes nothing — Hermes Update runs daily

Deploy Infrastructure (deploy-terragrunt.yml)

Section titled “Deploy Infrastructure (deploy-terragrunt.yml)”

The main deploy. It applies the whole environment with Terragrunt, then replaces the servers.

Input Meaning
environment staging-1 or production-1 for app deploys. staging-shared / production-shared apply only the network and database layer.
frontend_version ECR tag for volare/frontend, for example v1.42.0
backend_version ECR tag for volare/backend, volare/php-fpm and volare/queue-worker
deploy_hermes Also replace the Hermes server (default: no)
hermes_only Replace only Hermes; leave api, front and ops-runner alone

What it does:

  1. Notifies Hermes that a deploy started (a signed webhook; see below).
  2. Checks that the requested tags exist in ECR — a typo fails here, before anything changes.
  3. Runs terragrunt apply on the environment and its shared dependencies (VPC, load balancers, database).
  4. Starts an instance refresh on every app ASG: new servers boot with the new images, become healthy, then the old ones are terminated (min 100 % healthy, so no downtime).
  5. Waits up to 20 minutes for healthy servers, then notifies Hermes with the result and duration.
flowchart LR
  T[backend_version input] --> TF[Terragrunt renders<br/>docker-compose template]
  TF --> SSM[SSM parameter<br/>/volare/env/autoscaling/api/docker-compose]
  R[Instance refresh] --> NEW[New EC2 instance boots]
  SSM --> NEW
  NEW --> PULL[docker compose pull + up]

The frontend tag is written into the front servers’ start-up script instead, so changing it also creates a new launch template version. Either way, only new instances pick up a new tag — running servers are never updated in place.

Same inputs (staging-1 / production-1 only) and same refresh logic, but it applies only the autoscaling unit — skipping the network, DNS, database and target groups. Use it when you only ship new image tags. A new fast-lane run for the same environment cancels the one in progress.

Instance Refresh ASGs (instance-refresh.yml)

Section titled “Instance Refresh ASGs (instance-refresh.yml)”

Replaces every server in an environment (including Hermes) without changing any version. Use it after you edit a .env parameter in SSM or after a new AMI is built.

Runs on every infra-volare pull request touching terragrunt/ or packer/:

  • Posts the terragrunt plan of staging-1 (and the staging-shared units it depends on) as a PR comment.
  • Checks terraform fmt, validates Packer templates, and runs tfsec/checkov (advisory only).

Production is not planned in CI — review production changes carefully.

Plans Grafana alerting changes (terragrunt/live/us-east-2/global/, modules/grafana-alerting/) on pull requests and applies them automatically on merge to main. It also runs the module’s unit tests. See Monitoring and Alerts.

Builds one server image: ubuntu-docker.pkr.hcl (app servers) or ubuntu-hermes.pkr.hcl (Hermes, optionally pinned to a hermes_release). The new AMI is used by the next deploy or instance refresh of each environment.

Runs daily at 05:30 UTC. If a new stable Hermes Agent release exists, it builds a Hermes AMI and rolls it out to production, then staging, using Deploy Infrastructure with hermes_only. See Hermes.

Notify Hermes Deployment (notify-hermes-deployment.yml)

Section titled “Notify Hermes Deployment (notify-hermes-deployment.yml)”

A helper called by the deploy workflows. It sends a signed (HMAC) webhook to Hermes with the environment, versions, result and duration. If Hermes is unreachable it only logs a warning — it never fails a deploy.