version: ${version} debug: false persist: true machine: type: controlplane token: ${token} ca: crt: ${ca_crt} key: ${ca_key} certSANs: - ${lan_ip} %{ for san in cloudflare_talos_sans ~} - ${san} %{ endfor ~} network: hostname: ${hostname} interfaces: - interface: eno1 addresses: - ${lan_ip}/24 routes: - network: 0.0.0.0/0 gateway: ${lan_gateway} dhcp: false dhcpOptions: ipv6: false nameservers: %{ for ns in dns_servers ~} - ${ns} %{ endfor ~} extraHostEntries: - ip: ${forgejo_registry_ip} aliases: - ${forgejo_hostname} kubelet: image: ${kubelet_image} defaultRuntimeSeccompProfileEnabled: true disableManifestsDirectory: true clusterDNS: - ${cluster_dns_ip} extraArgs: rotate-server-certificates: true nodeIP: validSubnets: - 192.168.1.0/24 install: disk: ${install_disk} image: factory.talos.dev/installer/613e1592b2da41ae5e265e8789429f22e121aab91cb4deb6bc3c0b6262961245:${talos_version} wipe: true grubUseUKICmdline: true %{ if length(longhorn_disks) > 0 ~} disks: %{ for idx, disk in longhorn_disks ~} # ${disk.kind} — ${disk.device} - device: ${disk.device} partitions: - mountpoint: ${coalesce(disk.mountpoint, format("/var/lib/longhorn-disk%d", idx + 1))} %{ endfor ~} %{ endif ~} features: diskQuotaSupport: true kubePrism: enabled: true port: 7445 hostDNS: enabled: false nodeLabels: node.kubernetes.io/exclude-from-external-load-balancers: "" topology.kubernetes.io/region: homelab topology.kubernetes.io/zone: ${zone} %{ if !allow_scheduling ~} # Dedicated control plane — re-apply the control-plane taint that # allowSchedulingOnControlPlanes=true removed cluster-wide. nodeTaints: node-role.kubernetes.io/control-plane: ":NoSchedule" %{ endif ~} cluster: id: ${cluster_id} secret: ${cluster_secret} controlPlane: endpoint: https://${controlplane_ip}:6443 clusterName: ${cluster_name} # true removes the default control-plane taint from ALL CP nodes; dedicated # nodes (allow_scheduling=false) get it re-added via machine.nodeTaints above. allowSchedulingOnControlPlanes: true network: dnsDomain: ${dns_domain} podSubnets: %{ for subnet in pod_subnets ~} - ${subnet} %{ endfor ~} serviceSubnets: %{ for subnet in service_subnets ~} - ${subnet} %{ endfor ~} cni: name: none token: ${bootstrap_token} secretboxEncryptionSecret: ${secretbox_encryption_secret} ca: crt: ${kubernetes_ca_crt} key: ${kubernetes_ca_key} aggregatorCA: crt: ${aggregator_ca_crt} key: ${aggregator_ca_key} serviceAccount: key: ${service_account_key} apiServer: certSANs: - ${controlplane_ip} - ${lan_ip} %{ for san in cloudflare_apiserver_sans ~} - ${san} %{ endfor ~} image: ${kube_apiserver_img} admissionControl: - name: PodSecurity configuration: apiVersion: pod-security.admission.config.k8s.io/v1alpha1 defaults: audit: restricted audit-version: latest enforce: baseline enforce-version: latest warn: restricted warn-version: latest exemptions: namespaces: - kube-system runtimeClasses: [] usernames: [] kind: PodSecurityConfiguration auditPolicy: apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: Metadata controllerManager: image: ${controller_mgr_img} proxy: image: ${kube_proxy_img} disabled: true scheduler: image: ${scheduler_img} discovery: enabled: true registries: kubernetes: disabled: true service: {} etcd: # Pin etcd peer/advertise addresses to the LAN subnet explicitly. advertisedSubnets: - 192.168.1.0/24 ca: crt: ${etcd_ca_crt} key: ${etcd_ca_key} extraManifests: - https://raw.githubusercontent.com/alex1989hu/kubelet-serving-cert-approver/main/deploy/standalone-install.yaml - https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml inlineManifests: - name: cilium contents: | apiVersion: v1 kind: Namespace metadata: name: kube-system # Cilium LoadBalancer IPAM pool + L2 announcement policy. Substrate networking # (owned here alongside the Cilium install), single source of truth in # terraform/files/cilium/*.yaml. Provides LAN LoadBalancer IPs for ingress-nginx # (.160) and forgejo-ssh (.161). Was previously an ArgoCD app whose empty # kustomization never actually applied it (the live pool came from manual # kubectl); moved here so LB-IPAM exists before any LoadBalancer Service syncs. - name: cilium-lb-ippool contents: | ${indent(8, cilium_lb_ippool)} - name: cilium-l2-announcement contents: | ${indent(8, cilium_l2_announcement)} # CoreDNS Corefile with homelab hostname rewrites (single source of truth in # terraform/files/coredns/Corefile). In-cluster pods resolve *.riotpiao.com to # the nginx ingress controller so OIDC auto-discovery against # authentik.riotpiao.com works and the Host header is preserved. Owned by # Talos — do NOT also manage the coredns ConfigMap via ArgoCD. - name: coredns-config contents: | apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | ${indent(12, coredns_corefile)}