Add optional MetalLB platform support

This commit is contained in:
juvdiaz 2026-05-26 23:09:09 -06:00
parent 047aee8481
commit 7c0a74cf51
3 changed files with 103 additions and 0 deletions

View File

@ -44,6 +44,8 @@ accidentally modify the cluster.
3. `bootstrap/platform`
- installs a minimal Calico deployment through the Tigera operator
- installs NodeLocal DNSCache for node-local DNS query caching
- can install MetalLB for LAN `LoadBalancer` services after an address pool
is chosen
- installs OpenEBS
- creates `openebs-hostpath-retain`
- installs Argo CD
@ -240,6 +242,27 @@ rollout compatible with the current kube-proxy iptables path without rewriting
kubelet DNS settings across the nodes. Override `nodelocal_dns` if the service
CIDR or upstream DNS servers change.
## MetalLB
MetalLB is present in `bootstrap/platform` but disabled by default. Enable it
only after reserving a LAN IP range outside DHCP and outside any future OpenWrt
LAN pool:
```bash
export TF_VAR_metallb='{
enabled = true
repository = "https://metallb.github.io/metallb"
version = "0.16.0"
namespace = "metallb-system"
address_pool = ["192.168.100.240-192.168.100.250"]
l2_advertisement_enabled = true
pool_name = "homelab-lan"
}'
```
The current website, demos, registry, and Gitea services remain `NodePort`
services until the LAN address pool and edge route are tested manually.
## Secrets
Use SOPS with age for secrets that need to live in Git. Start from

View File

@ -514,6 +514,64 @@ resource "kubernetes_manifest" "nodelocal_dns_metrics_service" {
}
}
resource "helm_release" "metallb" {
for_each = var.metallb.enabled ? { enabled = true } : {}
depends_on = [null_resource.calico_ready]
name = "metallb"
repository = var.metallb.repository
chart = "metallb"
version = var.metallb.version
namespace = var.metallb.namespace
create_namespace = true
timeout = 600
wait = true
values = [
yamlencode({
frrk8s = {
enabled = false
}
})
]
}
resource "kubernetes_manifest" "metallb_ip_address_pool" {
for_each = var.metallb.enabled && length(var.metallb.address_pool) > 0 ? { enabled = true } : {}
depends_on = [helm_release.metallb]
manifest = {
apiVersion = "metallb.io/v1beta1"
kind = "IPAddressPool"
metadata = {
name = var.metallb.pool_name
namespace = var.metallb.namespace
}
spec = {
addresses = var.metallb.address_pool
}
}
}
resource "kubernetes_manifest" "metallb_l2_advertisement" {
for_each = var.metallb.enabled && var.metallb.l2_advertisement_enabled && length(var.metallb.address_pool) > 0 ? { enabled = true } : {}
depends_on = [kubernetes_manifest.metallb_ip_address_pool]
manifest = {
apiVersion = "metallb.io/v1beta1"
kind = "L2Advertisement"
metadata = {
name = var.metallb.pool_name
namespace = var.metallb.namespace
}
spec = {
ipAddressPools = [var.metallb.pool_name]
}
}
}
resource "helm_release" "openebs" {
depends_on = [null_resource.calico_ready]
name = "openebs"

View File

@ -112,6 +112,28 @@ variable "nodelocal_dns" {
}
}
variable "metallb" {
type = object({
enabled = bool
repository = string
version = string
namespace = string
address_pool = list(string)
l2_advertisement_enabled = bool
pool_name = string
})
default = {
enabled = false
repository = "https://metallb.github.io/metallb"
version = "0.16.0"
namespace = "metallb-system"
address_pool = []
l2_advertisement_enabled = true
pool_name = "homelab-lan"
}
}
variable "observability" {
type = object({
namespace = string