magicciv/infra/packer/golden-image.pkr.hcl
Natalie d9588f8c80 perf(infra): incremental golden-image rebuilds (layer on the last snapshot)
Packer base image is now a var; ./run dist:image builds FROM the newest
mc-golden snapshot by default, so the idempotent provision.sh only redoes changed
work (~3-8 min vs ~20 cold). --cold rebuilds from stock Ubuntu to reset layer
cruft. Made the clone step idempotent (clone-or-fetch) so it works on a
pre-provisioned base. Directly addresses 'avoid unnecessary rebuilds'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 14:41:01 -04:00

97 lines
2.6 KiB
HCL

// Bakes a DigitalOcean custom image (snapshot) with the full toolchain + a warm
// clone + a prebuilt GDExtension + a warm Godot import cache, so fleet workers
// boot build-ready in ~30s instead of running rustup/godot-install per spin-up.
//
// Build once:
// export DIGITALOCEAN_TOKEN=... // or pass -var do_token=...
// packer init infra/packer/golden-image.pkr.hcl
// packer build -var git_remote=https://gitlab.com/<you>/magic-civilization.git \
// infra/packer/golden-image.pkr.hcl
//
// The image is named mc-golden-<timestamp>; the test-fleet Terraform module
// auto-discovers the newest one by the "mc-golden" name substring.
packer {
required_plugins {
digitalocean = {
source = "github.com/digitalocean/digitalocean"
version = ">= 1.4.0"
}
}
}
variable "do_token" {
type = string
sensitive = true
default = env("DIGITALOCEAN_TOKEN")
}
variable "region" {
type = string
default = "nyc3"
}
# A one-off box builds the image (cargo + godot import are CPU-heavy); it only
# exists for the build. Basic s-* — CPU-Optimized c-* is tier-restricted on new
# DO accounts (needs a support ticket to unlock).
variable "build_size" {
type = string
default = "s-8vcpu-16gb-amd"
}
variable "git_remote" {
type = string
}
variable "git_ref" {
type = string
default = "main"
}
variable "remote_user" {
type = string
default = "mc"
}
variable "base_image" {
type = string
default = "ubuntu-24-04-x64"
# Stock Ubuntu for a COLD build, or a previous mc-golden snapshot ID for an
# INCREMENTAL rebuild — provision.sh is idempotent, so it only redoes changed
# work (~3-8 min vs ~20). `./run dist:image` picks this automatically.
}
variable "fleet_pubkey" {
type = string
default = ""
# The fleet SSH public key, baked into the build user's authorized_keys so the
# dispatch can ssh in without relying on cloud-init's (snapshot-flaky) key copy.
}
locals {
ts = formatdate("YYYYMMDDhhmmss", timestamp())
}
source "digitalocean" "golden" {
api_token = var.do_token
region = var.region
size = var.build_size
image = var.base_image
ssh_username = "root"
snapshot_name = "mc-golden-${local.ts}"
}
build {
sources = ["source.digitalocean.golden"]
provisioner "shell" {
environment_vars = [
"GIT_REMOTE=${var.git_remote}",
"GIT_REF=${var.git_ref}",
"BUILD_USER=${var.remote_user}",
"FLEET_PUBKEY=${var.fleet_pubkey}",
]
execute_command = "chmod +x {{ .Path }}; env {{ .Vars }} bash {{ .Path }}"
script = "${path.root}/provision.sh"
}
}