Files
homelab-infrastructure-as-code/03-k8s-infra/CLAUDE.md
T
kasun 6753be7f09
Deploy Proxmox Infra / Pulumi Preview (pull_request) Successful in 1m20s
Deploy Proxmox Infra / Pulumi Deploy (pull_request) Has been skipped
Deploy k8s Infra / Pulumi Preview (pull_request) Successful in 48s
Deploy k8s Infra / Pulumi Deploy (pull_request) Has been skipped
Deploy k8s Apps / Pulumi Preview (pull_request) Successful in 42s
Deploy k8s Apps / Pulumi Deploy (pull_request) Has been skipped
Deploy Monitoring / Pulumi Preview (pull_request) Successful in 49s
Deploy Monitoring / Pulumi Deploy (pull_request) Has been skipped
refactor code
2026-06-12 18:33:09 +02:00

2.2 KiB

k8s-infra

This file provides guidance to Claude Code when working in 03-k8s-infra. See the repo-root CLAUDE.md for shared conventions, deployment order, and CI/CD.

Cluster-level infrastructure for the k3s homelab cluster, deployed via Helm and @pulumi/kubernetes. Reads kubeconfig from k8s-bootstrap via StackReference.

Common Commands

npm install
pulumi refresh --yes && pulumi up --yes

CI installs the helm CLI (azure/setup-helm) before running Pulumi.

Architecture

Component What it does
NFS CSI Driver csi-driver-nfs Helm chart — enables NFS-backed PVCs
truenas-nfs StorageClass Backed by an NFS share on TrueNAS (Retain reclaim policy)
cert-manager Certificate lifecycle management
letsencrypt-prod ClusterIssuer DNS-01 via Cloudflare, issues Let's Encrypt TLS certs
Longhorn Default block storage (longhorn StorageClass, 3 replicas) — used by app/monitoring PVCs
kube-vip DaemonSet that ARP-announces a virtual IP for LoadBalancer Services
kube-vip-cloud-provider Allocates LoadBalancer IPs from a single-address pool (kubeVipAddress) — k3s's built-in ServiceLB is not used
traefik ServicePatch Pins Traefik's LoadBalancer IP to kubeVipAddress

Export: nfsStorageClass = "truenas-nfs".

Required Pulumi config

pulumi config set --secret truenasHost      <truenas-ip>
pulumi config set --secret truenasNfsPath   /mnt/pool/k8s
pulumi config set --secret cloudflareApiToken <cf-token>
pulumi config set --secret letsencryptEmail   <your-email>
pulumi config set --secret kubeVipAddress   <vip-ip>
pulumi config set kubeVipInterface          <e.g. eth0>

kubeconfig is read automatically via StackReference — do not set it here.

TrueNAS one-time setup (before deploying)

  1. Create dataset pool/k8s
  2. Add an NFS share for that dataset:
    • ACL type: POSIX/generic Unix permissions (not SMB/NFSv4 ACLs) on TrueNAS SCALE
    • Maproot User / Group: root / root
    • Allowed Hosts/Networks: restrict to the k3s node IPs/CIDR
  3. In Network → Allowed Networks, permit your LAN subnet (e.g. 192.168.1.0/24)

CI/CD

Workflow: ../.gitea/workflows/03-deploy-k8s-infra.yaml. Secret: K8S_INFRA_PULUMI_DEV_YAML.