Appendix: Local Development Environment
Incident Hook
A learner tests every infrastructure and GitOps change only against the cloud cluster. Feedback is slow, mistakes are expensive, and trivial YAML errors burn real time and real money. By the time the change reaches the shared environment, the debugging loop is already too wide. A local cluster exists to reduce that blast radius before cloud validation even starts.
Why This Appendix Exists
The main course teaches the production path first. This appendix shows the fastest safe feedback loop for local experimentation:
- a Terraform-managed
kindcluster - generated kubeconfig and context wiring
- optional local image registry
- Flux bootstrap for GitOps-shaped testing
Use it when you need fast iteration on manifests, hooks, or application behavior before touching Hetzner-backed environments.
SafeOps Baseline
In the current SafeOps implementation:
- Terraform manages the lifecycle of the local
kindcluster. - the cluster is multi-node, so scheduling behavior is closer to reality than a single-node toy setup.
- Flux Operator +
FluxInstancecan bootstrap the local cluster from the same GitOps layout. - local registry support keeps image iteration fast.
Investigation Snapshots
Here is the Terraform module layout used for the local cluster in the SafeOps system.
Local kind cluster Terraform module
Snippet unavailable during this build.
Here is the local development runbook used in the SafeOps system.
Local development runbook
Snippet unavailable during this build.
Safe Workflow (Step-by-Step)
- Confirm local prerequisites first: Docker Engine, Terraform,
kubectl,make, and enough CPU/RAM for a three-nodekindcluster. - Move to
infra/terraform/kind_cluster/and decide whether local Flux should reconcile from the same Git path as the main platform. - If you want GitOps reconciliation locally, export the Flux repository variables before apply.
- Run
terraform initandterraform applyfrom thekind_clustermodule. - Point
kubectlto the generated kubeconfig or switch to the mergedsre-control-planecontext. - Verify nodes, namespaces, and Flux controllers before testing workloads.
- If you iterate on images, start the local registry before cluster apply so the mirror config is valid.
- Tear the cluster down with
terraform destroywhen the test cycle is finished.
Verification Commands
cd infra/terraform/kind_cluster
terraform init
terraform apply
export KUBECONFIG="$(pwd)/kubeconfig.yaml"
kubectl config use-context sre-control-plane
kubectl get nodes
kubectl -n flux-system get pods
Optional local registry:
docker run -d --restart=always -p 5001:5000 --name kind-registry registry:2
When to Prefer Local Development
Prefer the local path when:
- you are validating manifests, hooks, or GitOps wiring
- you need a fast loop for backend or frontend changes
- you want to reproduce a failure without risking shared environments
Do not treat the local path as a substitute for provider-realistic verification. Hetzner, external DNS, cloud load balancers, and real certificate issuance still need cloud-side validation.
Guardrail Principle
Use the local cluster to shrink the feedback loop and the blast radius. Use the cloud cluster to validate provider-specific behavior. Do not confuse the two.
Done When
- you can create and destroy the local cluster from Terraform
kubectlcan target the local context without ambiguity- Flux controllers reconcile in the local cluster when enabled
- you can explain which tests belong locally and which still require cloud validation