Core Track Guardrails-first chapter in core learning path.

Estimated Time

  • Reading: 10 min
  • Lab: 30-45 min (mostly waiting for images)
  • Quiz: 5 min

Prerequisites

What You Will Produce

A local kind cluster reconciled by Flux from your own fork, every Kustomization Ready, your own age key registered for SOPS, and the three verification commands you will run at the start of every later chapter.

Chapter 00: Your Lab Environment

Every hands-on chapter from 02 onwards runs against one local cluster that you build here once. Nothing in the core track needs a cloud account, a domain, or an API key: the cluster runs in Docker with kind, and Flux reconciles the local profile of the SafeOps platform - the production GitOps tree minus the parts that only make sense with a cloud provider.

Read Chapter 01 for the ideas; do this chapter when you are ready to type.

Learning Objectives

By the end of this chapter, you will be able to:

  • Provision the SafeOps kind cluster with Terraform and prove that Flux is green
  • Explain which platform components the local profile leaves out, and why
  • Generate your own age key and register it for the secrets you will encrypt in Chapter 04
  • Run a test pod in an environment namespace that enforces Pod Security restricted

1. Install the Tools

ToolWhyCheck
Docker (OrbStack, Docker Desktop, Colima) with ~6 CPU / 8 GBthe cluster nodes are containersdocker info
Terraform ≥ 1.5provisions the cluster and the Flux bootstrapterraform version
kind ≥ 0.30local Kuberneteskind version
kubectl, flux CLIyou will use both constantlykubectl version --client, flux version --client
age, sopsChapter 04age-keygen --version, sops --version
pre-commit, makeChapters 02 and 05pre-commit --version

2. Get the Platform Repository

The course is taught from the SafeOps reference implementation. Fork it, then clone your fork - from Chapter 03 on you will commit to it and Flux will deploy from it.

git clone https://github.com/<you>/sre.git
cd sre

The upstream repository is public; a fork is public by default too, and Flux reads it anonymously. Only if you make your fork private does Flux need a token: create a GitHub personal access token with repo read scope and pass it as TF_VAR_flux_git_token.

3. Build the Cluster

cd infra/terraform/kind_cluster
export TF_VAR_flux_git_repository_url="https://github.com/<you>/sre.git"   # your fork
# export TF_VAR_flux_git_token="<PAT with repo read>"                      # only for a private fork
terraform init
terraform plan -out=tfplan      # read it: 2 nodes, Traefik, metrics-server, Flux, generated secrets
terraform apply tfplan

Two to three minutes later the cluster exists and Flux starts pulling images. Terraform also:

  • merges the kubeconfig into ~/.kube/config as context sre-control-plane
  • generates the runtime secrets the applications need (backend-secrets, app-postgres-app, MinIO credentials) - never committed, unique to your cluster
  • generates age.agekey in the repository root (git-ignored) and stores it in the cluster as sops-age

4. Register Your Key for SOPS

cd ../../..                      # back to the repository root
scripts/sops-setup.sh --local
git add .sops.yaml && git commit -m "sops: register my local key" && git push

This writes your public key into the flux/secrets/local/ rule of .sops.yaml. Only files under that path are encrypted for you; the platform’s own secrets stay encrypted for the platform key, which you do not have and do not need.

5. Prove It Is Green

Wait for the images to arrive (five minutes on a normal connection), then:

kubectl config use-context sre-control-plane
flux get kustomizations -A          # every row READY=True
kubectl get pods -A --no-headers | grep -vE 'Running|Completed'   # prints nothing
make smoke-test                     # 9/9

These three commands are your baseline check. Every later chapter starts by running them; if they are not clean, fix the environment before you start the exercise, not after.

6. What the Local Profile Contains

On your kind clusterCloud track only (Hetzner profile)
namespaces develop, staging, production, lab with NetworkPolicies, quotas, Pod Securitycert-manager, external-dns, Cloudflare DNS/TLS (appendix)
backend + frontend in all three environments, Traefik ingress on localhost:8080Dex, Headlamp, OIDC RBAC
Prometheus + Grafana (kubectl -n observability port-forward svc/kube-prometheus-stack-grafana 3000:80)Uptrace tracing export
CloudNativePG with one Postgres cluster per environment, backups to MinIOk8s-ai-monitor (needs an LLM key - Chapter 13)
Kyverno with both policy packs in Audit, Flagger canaries, Chaos MonkeyFlux image automation (writes back to Git)

When a chapter says “Cloud track”, that step needs something from the right-hand column. Read it, understand it, and move on - the core exercise works on the left-hand column alone.

7. Running Test Pods

The environment namespaces enforce Pod Security restricted. A plain kubectl run busybox is rejected before it starts - that is a guardrail, not a bug. The course uses a wrapper that adds the required security context:

scripts/lab-pod.sh -n develop -i curlimages/curl -l app=frontend -- curl -sf http://backend/healthz
scripts/lab-pod.sh -n develop --daemon np-debug     # long-lived; then kubectl -n develop exec np-debug -- ...

The lab namespace is the exception: Pod Security only warns there, so drills that must observe a violation (Chapter 15) can run.

8. Tear Down and Rebuild

cd infra/terraform/kind_cluster && make destroy     # cluster and state gone
terraform apply                                     # ...and back, same fork, same key

Rebuilding is cheap. When a chapter leaves your cluster in a state you do not understand, rebuild rather than debug the debugging.


Knowledge Check

Complete the Quiz before Chapter 01 - it checks that you can tell your own responsibilities (fork, key, token) from what the automation does for you.

Hands-On Materials

Labs, quizzes, and runbooks — available to course members.

  • Quiz: Chapter 00 (Your Lab Environment) Members