Skip to content

Working on infra-volare

Read this before you open a pull request in volare-tech/infra-volare. Most product work never needs it.

infra-volare/
├── terragrunt/
│ ├── root.hcl # Shared config: region, AWS profile, S3 state, providers
│ ├── live/us-east-2/ # One folder per environment, one sub-folder ("unit") per component
│ │ ├── staging-shared/ # vpc, load-balancer, postgresql, twingate-*, *-private-dns
│ │ ├── staging-1/ # autoscaling, target-groups, cloudflare-dns, s3/cloudfront, hermes-*
│ │ ├── production-shared/
│ │ ├── production-1/ # + s3-db-dumps
│ │ └── global/grafana-alerting/
│ ├── modules/ # Reusable Terraform modules used by the units
│ └── templates/ # docker-compose and Hermes templates rendered into SSM
├── packer/ # AMI definitions + Ansible playbooks
├── grafana/ # Dashboards (JSON) and troubleshooting notes
├── scripts/ # Operational helper scripts (below)
├── docs/ # Design plans and the alerts runbook (some pages in Spanish and outdated)
└── .github/workflows/ # Deploy, plan, Packer, monitoring and Hermes workflows

Each unit (for example production-1/autoscaling) has a terragrunt.hcl that points to a module in modules/ and passes its inputs. Units declare dependencies on each other, also across folders (staging-1/autoscaling depends on staging-shared/vpc).

  • Terraform 1.10.1 and Terragrunt 0.99.1 (pinned in .terraform-version / .terragrunt-version; tfenv/tgenv pick them up)
  • AWS CLI v2 and jq
  • Packer and Ansible — only to work on AMIs
  • Python 3 — only to run module tests

root.hcl picks the AWS profile from the folder: paths under production-1 or production-shared use volare-production, everything else uses volare. All Terraform state lives in an S3 bucket in the staging account (volare profile), so a production plan needs both profiles.

Terminal window
# Secrets the providers need — get them from the team secret store
export TWINGATE_API_KEY=... POSTGRESQL_ADMIN_PASSWORD=... CLOUDFLARE_API_TOKEN=...
# Pin the image tags currently deployed, or the plan will try to roll servers to latest/master
export BACKEND_VERSION=v1.42.0 FRONTEND_VERSION=v1.42.0
# One unit
cd terragrunt/live/us-east-2/staging-1/autoscaling
terragrunt plan
# A whole environment plus its shared dependencies (what CI does)
cd terragrunt/live/us-east-2/staging-1
terragrunt run --all --queue-include-external -- plan

Prefer letting CI plan and apply. Apply locally only when you know why the workflows cannot.

  1. Branch from main and open a PR.
  2. PR Plan comments the staging-1 plan and checks formatting, Packer templates and security scanners. Production is not planned — read production diffs carefully.
  3. Merge. Changes under global/ (alerts) are applied automatically. Environment changes are not: run Deploy Infrastructure (or Fast-lane) for each environment, passing the image tags that are currently deployed.
  4. Merge your branch before anyone else deploys from main, or Terraform will remove your resources (see Deploy Workflows).

Before pushing: terraform fmt -recursive terragrunt/, and python3 -m unittest discover -s terragrunt/modules/<module>/tests for modules that have tests.

Script Use
passport-keys-to-ssm.sh <env> [--rotate] Generates the Passport RSA keys for the Arkana MCP OAuth and appends them to the backend .env parameter. Refuses to overwrite without --rotate.
asg_set_capacity.sh <asg> <desired> [--set-min] [--set-max] Change an ASG’s desired count. It is clamped to the current min/max unless you pass the flags.
env_off.sh <env> [--with-rds] / env_on.sh <env> [--with-rds] Scale an environment’s servers to 0 / 1 (and stop/start RDS). Only effective on staging — production minimums stay at 2.
rds_power.sh <on|off> <db-id> Start or stop an RDS instance.
resolve_env_ids.sh <env> Print the ASG names and RDS id of an environment (run from scripts/).
hermes-update-deploy.sh <env> Used by the Hermes Update workflow.
debug-*.sh, verify-alloy-optimization.sh Run on a server to troubleshoot Grafana Alloy.
ssm/deploy-*.sh Legacy — do not use.

All scripts need AWS_REGION=us-east-2 (or --region) and the right AWS_PROFILE.