feat: Added automatic script copying functionality

This commit is contained in:
2026-07-10 22:58:56 +01:00
parent 41d93563d0
commit bab789a347
23 changed files with 284 additions and 18 deletions
+76
View File
@@ -94,6 +94,14 @@ resource "hcloud_volume" "storage" {
}
}
locals {
# Hetzner's automount convention (hc-utils' 99-hc-volume-automount.rules) is
# always /mnt/HC_Volume_<id> - deterministic once the volume exists, since the
# id is stable for the volume's lifetime regardless of which server it's
# attached to.
data_dir = "/mnt/HC_Volume_${hcloud_volume.storage.id}"
}
# Renders services/dev/Runners/docker-compose.yml directly into the repo, with
# one runner service per var.runner_count. This only touches the local working
# tree - deploying the change still goes through the normal scp + spinup.sh flow.
@@ -101,6 +109,74 @@ resource "local_file" "runners_compose" {
filename = "${path.root}/../services/dev/Runners/docker-compose.yml"
content = templatefile("${path.module}/templates/runners-docker-compose.yml.tftpl", {
runner_count = var.runner_count
data_dir = local.data_dir
})
file_permission = "0644"
}
# DATA_DIR is picked up automatically by `docker compose` (which auto-loads
# .env from its working directory) for every dev/*-docker-compose.yml bind
# mount - see services/dev/*.yml. Not committed (see .gitignore): it's tied to
# the live volume's ID, so it's regenerated by tofu apply, not handed off via git.
resource "local_file" "env" {
filename = "${path.root}/../services/dev/.env"
content = "DATA_DIR=${local.data_dir}\n"
file_permission = "0644"
}
locals {
# Everything under services/dev except the two files above: those are
# tracked via their own resource content (reading them back with fileset()/
# filesha1() before they exist would fail during `tofu plan`).
dev_static_files = sort([
for f in fileset("${path.root}/../services/dev", "**") :
f if f != ".env" && f != "Runners/docker-compose.yml"
])
dev_static_files_hash = sha1(join("", [
for f in local.dev_static_files : filesha1("${path.root}/../services/dev/${f}")
]))
}
# Copies services/dev to the server on every apply that changes it (a hand-edited
# compose file, a new runner count, ...) or recreates the server - not just once
# at first creation. Split from hcloud_server.this because it must run after the
# generated files above, which in turn depend on the volume, which depends on
# the server - so it can't be a provisioner on the server resource itself.
resource "null_resource" "deploy_services" {
triggers = {
server_id = hcloud_server.this.id
static_files = local.dev_static_files_hash
env = local_file.env.content
runners = local_file.runners_compose.content
}
connection {
type = "ssh"
host = hcloud_server.this.ipv4_address
user = "root"
private_key = file(var.ssh_private_key_path)
}
provisioner "remote-exec" {
inline = ["mkdir -p /home/${var.deploy_user}/services"]
}
provisioner "file" {
source = "${path.root}/../services/dev"
destination = "/home/${var.deploy_user}/services"
}
provisioner "remote-exec" {
inline = [
"chown -R ${var.deploy_user}:${var.deploy_user} /home/${var.deploy_user}/services",
"chmod +x /home/${var.deploy_user}/services/dev/*.sh",
]
}
depends_on = [
hcloud_server.this,
local_file.env,
local_file.runners_compose,
]
}