ci: gitea: runners infra
runner nix smoke / nix label smoke (push) Has been cancelled
runner ubuntu smoke / ubuntu-latest label smoke (push) Has been cancelled

This commit is contained in:
2026-06-08 08:18:08 +00:00
parent f4a59ff117
commit 5a0696ce64
23 changed files with 1402 additions and 12 deletions
+90
View File
@@ -0,0 +1,90 @@
# Gitea runner OpenTofu backend contract
This directory defines the safe backend, provider contract, and kube-hetzner
cluster stack for the Gitea runner Kubernetes cluster.
## Required backend
Production state must use the OpenTofu S3 backend in `backend.tf`:
- bucket: `gitea-runner-hectic-lab`
- key: `gitea-runners/kube-hetzner/terraform.tfstate`
- region: `fsn1`, aligned with the target Hetzner location
- encryption: `encrypt = true`
- locking: `use_lockfile = true` where the selected S3-compatible endpoint
supports it
Before any production `tofu init`, verify the S3-compatible endpoint, credential
source, bucket versioning, encryption behavior, and lockfile support for the
chosen object-storage provider. Keep backend authentication externalized through
environment variables, AWS-compatible shared config, or the production secret
injection path from Task 3. Do not add `access_key`, `secret_key`, Hetzner
tokens, runner tokens, kubeconfig material, or decrypted SOPS data to checked-in
OpenTofu files.
## Local state safety
Production local state is forbidden. Only syntax-only validation/prototyping may
use local state, and it must use backend-disabled initialization:
```sh
tofu -chdir=infra/gitea-runners/opentofu init -backend=false
tofu -chdir=infra/gitea-runners/opentofu validate
```
Fail the run if production local state appears:
```sh
test ! -e infra/gitea-runners/opentofu/terraform.tfstate
test ! -e infra/gitea-runners/opentofu/terraform.tfstate.backup
grep -R 'backend "s3"' infra/gitea-runners/opentofu
```
The `.gitignore` in this directory blocks local state, plans, downloaded
providers/modules, and variable files from being committed. Treat any local
state file as disposable validation residue, never as production state.
## Provider and module pins
`versions.tf` pins the OpenTofu-compatible Hetzner Cloud provider to
`hetznercloud/hcloud` version `1.60.1`. kube-hetzner research for this plan
observed module version `2.19.3`, source `kube-hetzner/kube-hetzner/hcloud`, and
module minimum hcloud provider requirement `>= 1.59.0`; these values are recorded
as locals so Task 5 can wire the module without re-opening the version contract.
`providers.tf` leaves the `hcloud` provider empty so authentication comes from
the provider's external environment/config mechanisms such as `HCLOUD_TOKEN`.
Do not set token values in `.tf` or `.tfvars` files.
## Cluster shape
The default cluster is deliberately fixed-size:
- cluster name: `gitea-runners`
- Hetzner location: `fsn1`
- private network region: `eu-central`
- control plane: one `cpx21` node in pool `control-plane`
- workers: three `cpx31` nodes in pool `runner-workers`
- storage: Hetzner CSI enabled with expected StorageClass `hcloud-volumes`
- Longhorn: disabled
- autoscaling/KEDA: not enabled in this stack
The three default workers are sized for the initial five trusted privileged DinD
jobs. To scale toward ten jobs later, keep autoscaling disabled and either raise
`worker_count` to `5` or increase `worker_server_type`, then run a fresh
`tofu plan` and the Task 11 Kubernetes pressure checks before applying.
Required inputs must come from environment or secret injection, for example
`TF_VAR_hcloud_token`, `TF_VAR_ssh_public_key`, and `TF_VAR_ssh_private_key`.
Do not commit `.tfvars` files. kube-hetzner v2.19.3 writes the generated
kubeconfig to `./<cluster_name>_kubeconfig.yaml` when `create_kubeconfig` is
enabled; this path is ignored as operational secret material.
## Known state caveat
kube-hetzner may thread `hcloud_token` into Kubernetes secrets/state through its
internal `kube_system_secrets` handling. This task does not claim that risk is
solved. Task 5 must verify the generated plan and state before production apply
and prove that Hetzner tokens, S3 credentials, runner tokens, kubeconfig private
keys, and decrypted secrets are absent from committed files and unsafe state
evidence.