{"id":51289379,"url":"https://github.com/smoketurner/devbox-infra","last_synced_at":"2026-06-30T09:01:51.014Z","repository":{"id":365751750,"uuid":"1272871234","full_name":"smoketurner/devbox-infra","owner":"smoketurner","description":"Terraform templates to deploy devbox","archived":false,"fork":false,"pushed_at":"2026-06-25T20:27:06.000Z","size":220,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-25T22:08:52.399Z","etag":null,"topics":["devbox"],"latest_commit_sha":null,"homepage":"https://devbox.farm","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smoketurner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-18T02:26:39.000Z","updated_at":"2026-06-25T20:27:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/smoketurner/devbox-infra","commit_stats":null,"previous_names":["smoketurner/devbox-infra"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/smoketurner/devbox-infra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smoketurner%2Fdevbox-infra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smoketurner%2Fdevbox-infra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smoketurner%2Fdevbox-infra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smoketurner%2Fdevbox-infra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smoketurner","download_url":"https://codeload.github.com/smoketurner/devbox-infra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smoketurner%2Fdevbox-infra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34959509,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devbox"],"created_at":"2026-06-30T09:01:49.198Z","updated_at":"2026-06-30T09:01:51.008Z","avatar_url":"https://github.com/smoketurner.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# devbox-infra\n\nTerraform for the **devbox** platform: pre-warmed cloud dev boxes claimed through a\ncontrol plane. This repo provisions the AWS infrastructure. The application code it\nruns lives in the sibling repo\n[`smoketurner/devbox`](https://github.com/smoketurner/devbox), checked out alongside\nthis one as `../devbox`.\n\n## Relationship to `smoketurner/devbox`\n\n`smoketurner/devbox` is a Rust Cargo workspace (`../devbox/crates/`) that produces\nthree binaries:\n\n| Crate          | Binary         | Role                                              |\n| -------------- | -------------- | ------------------------------------------------- |\n| `devbox-cli`   | `devbox`       | user-facing CLI (claim/connect to a box)          |\n| `devbox-agent` | `devbox-agent` | on-host agent baked into the golden AMI           |\n| `devbox-server`| `devbox-server`| the control-plane service                         |\n\nThis repo **consumes** those build artifacts; it does not build them:\n\n- **`release.yml`** (on `v*` tags) publishes the `devbox-agent` binary to GitHub\n  Releases (`devbox-agent-{aarch64,x86_64}-unknown-linux-musl` + `SHA256SUMS`).\n  `image-builder` downloads the arm64 binary and bakes it into the golden AMI\n  (`var.devbox_agent_url`, default the `latest` release; pin with `var.devbox_agent_sha256`).\n- **`deploy.yml`** (on push to `main`) builds the `devbox-server` container image and\n  pushes it to the ECR repo created by `control-plane`, which then rolls the ECS service.\n\n## Build pipeline\n\nThe two builders are chained through SSM Parameter Store: each publishes the id of\nwhat it produced, and the next stage resolves it. Nothing is hardcoded.\n\n```\n  smoketurner/devbox              devbox-infra (this repo)\n  ──────────────────              ────────────────────────\n\n  release.yml\n   └─ devbox-agent ──────▶ image-builder ──[/devbox/ami/latest]──────────┐\n       (GitHub Release)     (golden AMI)                                  │\n                                  │                                       ├─▶ pool ──▶ running\n                                  ▼ AMI                                   │   (warm     dev box\n                           snapshot-builder ─[/devbox/workspace-snapshot/─┘    ASG)\n                           (warm /workspace)  latest]\n\n  deploy.yml\n   └─ devbox-server ─▶ ECR ─▶ control-plane (ECS) ──▶ sets pool desired capacity\n```\n\n| SSM parameter                        | Producer         | Consumers                |\n| ------------------------------------ | ---------------- | ------------------------ |\n| `/devbox/ami/latest`                 | image-builder    | snapshot-builder, pool   |\n| `/devbox/workspace-snapshot/latest`  | snapshot-builder | pool                     |\n\n## Modules\n\n### `image-builder` — the golden AMI\n\nAn EC2 Image Builder pipeline on Amazon Linux 2023 (arm64/Graviton). Components install\nthe toolchains (Go, Rust, Node 22, Python, uv, Docker), pre-pull container images,\ndownload `devbox-agent` to `/usr/local/sbin/devbox-agent`, and install the systemd units\nand SSH config that drive the agent on a running box:\n\n- `devbox-warmup.service` → `devbox-agent warmup` (freshen `/workspace`, self-tag `devbox:ready=true`)\n- `devbox-owner-sync.service` → `devbox-agent owner-sync` (provision the claimant's login account)\n- SSHD `AuthorizedPrincipalsCommand` → `devbox-agent principals %u` (per-claim auth against Vouch CA certs)\n\nPublishes the resulting AMI id to `/devbox/ami/latest`.\n\n### `snapshot-builder` — the warm workspace snapshot\n\nLaunches a throwaway builder from the golden AMI, formats a data volume, and runs\n`devbox-agent checkout` (see `scripts/clone-warm.sh`) to clone the configured repos\nsource-only into `/workspace` and run each repo's `.devbox/warm.sh` hook — seeding the\ntoolchain caches so a fresh box starts warm. Snapshots the volume and publishes the\nsnapshot id to `/devbox/workspace-snapshot/latest`. Runs on a schedule.\n\n### `pool` — the warm fleet\n\nAn Auto Scaling Group whose launch template resolves the golden AMI\n(`resolve:ssm:/devbox/ami/latest`) and attaches the latest workspace snapshot as\n`/workspace`. Instances run the baked agent (warmup → `devbox:ready=true`). The control\nplane sets desired capacity.\n\n### `control-plane` — orchestration\n\nAn ECS Fargate service running `devbox-server` from ECR, behind an NLB with TLS. Handles\nauth (Vouch OIDC), claims, and reconciles the pool ASG desired capacity.\n\n### `vpc` — networking\n\nThe shared VPC, subnets, and routing the other modules build on.\n\n## The agent contract (important when changing it)\n\n`image-builder`, `snapshot-builder/scripts/clone-warm.sh`, and the on-box systemd units\nall call `devbox-agent` subcommands and rely on the `DEVBOX_GITHUB_*` env vars the agent\nreads. A new agent binary reaches running infra **only through a new golden AMI**, so a\nchange in `../devbox` that infra depends on must roll out in order:\n\n1. Merge the agent change in `smoketurner/devbox` → `release.yml` publishes the binary.\n2. Run the `image-builder` pipeline → `/devbox/ami/latest` updates to an AMI with it.\n3. Only then land the infra change.\n\nLanding infra first breaks the next build/boot (a new subcommand is `command not found`;\na renamed env var silently disables auth). See `CLAUDE.md`.\n\n## Layout\n\n```\n.\n├── environments/        # Per-environment Terraform roots (reference modules/)\n│   └── dev/\n├── modules/\n│   ├── image-builder/   # golden AMI (EC2 Image Builder)\n│   ├── snapshot-builder/# warm /workspace EBS snapshot\n│   ├── pool/            # warm-box Auto Scaling Group\n│   ├── control-plane/   # devbox-server on ECS Fargate\n│   └── vpc/             # shared networking\n├── Makefile\n└── README.md\n```\n\n## Conventions\n\n- Standard Terraform file split per module: `main.tf`, `variables.tf`, `outputs.tf`,\n  `locals.tf`, `data.tf`, `iam.tf`, `versions.tf`, etc.\n- Shell scripts under `modules/*/scripts/` run via SSM run-command with no shebang\n  (AL2023 `/bin/sh` is bash). Lint with `shellcheck` and `shfmt -i 2`.\n\n## Usage\n\nEach environment root references the shared `modules/`. The `Makefile` wraps the common\nTerraform commands; its targets assume `AWS_PROFILE=dev-admin` and default to `ENV=dev`.\n\n```bash\nmake fmt        # terraform fmt -recursive\nmake validate   # fmt + terraform validate\nmake plan\nmake apply\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmoketurner%2Fdevbox-infra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmoketurner%2Fdevbox-infra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmoketurner%2Fdevbox-infra/lists"}