Files
foxhunt/infra/modules/ci-runner/main.tf
jgrusewski 903bf4fbf6 infra(ci): scale-to-zero with idle shutdown and auto-start watcher
CI runner auto-shuts down after 15min idle (no GITEA-ACTIONS containers).
Gitea server polls every 60s for queued runs and starts instance via SCW API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:33:42 +01:00

111 lines
3.0 KiB
HCL

# Security group: drop all inbound (Tailscale-only access)
resource "scaleway_instance_security_group" "ci_runner" {
name = "${var.instance_name}-sg"
zone = var.zone
inbound_default_policy = "drop"
outbound_default_policy = "accept"
}
resource "scaleway_instance_ip" "ci_runner" {
zone = var.zone
}
resource "scaleway_instance_server" "ci_runner" {
name = var.instance_name
type = var.instance_type
image = var.image
zone = var.zone
ip_id = scaleway_instance_ip.ci_runner.id
security_group_id = scaleway_instance_security_group.ci_runner.id
root_volume {
size_in_gb = var.root_volume_size_gb
}
user_data = {
cloud-init = templatefile("${path.module}/cloud-init.yaml.tpl", {
tailscale_auth_key = var.tailscale_auth_key
instance_name = var.instance_name
gitea_url = var.gitea_url
runner_token = var.runner_token
runner_labels = var.runner_labels
runner_capacity = var.runner_capacity
idle_timeout_minutes = var.idle_timeout_minutes
})
}
tags = ["ci", "foxhunt"]
}
# --- Auto-start watcher on Gitea server ---
# Deploys a systemd timer on the Gitea host that polls for queued runs
# and starts the CI instance via Scaleway API when needed.
resource "terraform_data" "ci_watcher" {
depends_on = [scaleway_instance_server.ci_runner]
triggers_replace = {
script = filesha256("${path.module}/ci-watcher.sh.tpl")
zone = var.zone
server = scaleway_instance_server.ci_runner.id
}
connection {
type = "ssh"
host = var.gitea_tailscale_host
user = "root"
}
# Deploy credentials file
provisioner "remote-exec" {
inline = [
"mkdir -p /etc/foxhunt /opt/foxhunt",
"cat > /etc/foxhunt/scw-credentials <<'EOF'",
"SCW_SECRET_KEY=${var.scw_secret_key}",
"SCW_CI_INSTANCE_ID=${scaleway_instance_server.ci_runner.id}",
"SCW_CI_ZONE=${var.zone}",
"GITEA_DB=/var/lib/gitea/data/gitea.db",
"EOF",
"chmod 0600 /etc/foxhunt/scw-credentials",
]
}
# Deploy watcher script
provisioner "file" {
content = templatefile("${path.module}/ci-watcher.sh.tpl", {})
destination = "/opt/foxhunt/ci-watcher.sh"
}
# Deploy systemd units and enable timer
provisioner "remote-exec" {
inline = [
"chmod +x /opt/foxhunt/ci-watcher.sh",
# Service unit
"cat > /etc/systemd/system/ci-watcher.service <<'EOF'",
"[Unit]",
"Description=Check for queued Gitea Actions runs and start CI runner",
"",
"[Service]",
"Type=oneshot",
"ExecStart=/opt/foxhunt/ci-watcher.sh",
"EOF",
# Timer unit
"cat > /etc/systemd/system/ci-watcher.timer <<'EOF'",
"[Unit]",
"Description=Poll for queued CI runs every 60s",
"",
"[Timer]",
"OnBootSec=30s",
"OnUnitActiveSec=60s",
"AccuracySec=10s",
"",
"[Install]",
"WantedBy=timers.target",
"EOF",
"systemctl daemon-reload",
"systemctl enable --now ci-watcher.timer",
]
}
}