91 lines
3.8 KiB
Markdown
91 lines
3.8 KiB
Markdown
# 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.
|