my-homelab-configs/bootstrap/cluster/main.tf

156 lines
4.7 KiB
HCL

terraform {
required_version = ">= 1.0"
required_providers {
null = {
source = "hashicorp/null"
version = "~> 3.2"
}
external = {
source = "hashicorp/external"
version = "~> 2.3"
}
}
}
resource "null_resource" "kubeadm_control_plane" {
triggers = {
node_name = var.control_plane_node_name
advertise_address = var.control_plane_advertise_address
pod_network_cidr = var.pod_network_cidr
kubeconfig_path = var.kubeconfig_path
kubeconfig_owner = var.kubeconfig_owner
registry_endpoint = var.registry_endpoint
persistent_volume_dirs = join(",", var.persistent_volume_dirs)
}
provisioner "local-exec" {
interpreter = ["/bin/bash", "-lc"]
command = <<EOT
set -euo pipefail
sudo apt-get update
sudo apt-get install -y open-iscsi nfs-common
sudo systemctl enable --now iscsid
sudo systemctl enable --now kubelet || true
sudo mkdir -p /etc/containerd
if [ ! -f /etc/containerd/config.toml ]; then
sudo containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
fi
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo sed -i 's#config_path = ""#config_path = "/etc/containerd/certs.d"#' /etc/containerd/config.toml
sudo mkdir -p /etc/containerd/certs.d/${self.triggers.registry_endpoint}
sudo tee /etc/containerd/certs.d/${self.triggers.registry_endpoint}/hosts.toml >/dev/null <<REGISTRY_EOT
server = "http://${self.triggers.registry_endpoint}"
[host."http://${self.triggers.registry_endpoint}"]
capabilities = ["pull", "resolve", "push"]
skip_verify = true
REGISTRY_EOT
sudo systemctl restart containerd
IFS=',' read -r -a pv_dirs <<< "${self.triggers.persistent_volume_dirs}"
for path in "$${pv_dirs[@]}"; do
sudo mkdir -p "$path"
sudo chmod 0775 "$path"
done
if [ ! -f /etc/kubernetes/admin.conf ]; then
sudo kubeadm init \
--pod-network-cidr=${self.triggers.pod_network_cidr} \
--node-name=${self.triggers.node_name} \
--apiserver-advertise-address=${self.triggers.advertise_address}
fi
mkdir -p "$(dirname "${self.triggers.kubeconfig_path}")"
sudo cp -f /etc/kubernetes/admin.conf "${self.triggers.kubeconfig_path}"
sudo chown ${self.triggers.kubeconfig_owner} "${self.triggers.kubeconfig_path}"
kubectl --kubeconfig "${self.triggers.kubeconfig_path}" taint nodes "${self.triggers.node_name}" node-role.kubernetes.io/control-plane- || true
EOT
}
}
data "external" "kubeadm_join_command" {
depends_on = [null_resource.kubeadm_control_plane]
program = [
"bash",
"-lc",
<<EOT
set -euo pipefail
cmd="$(sudo kubeadm token create --print-join-command)"
printf '{"cmd":"%s"}\n' "$(printf '%s' "$cmd" | sed 's/\\/\\\\/g; s/"/\\"/g')"
EOT
]
}
resource "null_resource" "kubeadm_worker" {
for_each = var.worker_nodes
depends_on = [data.external.kubeadm_join_command]
triggers = {
node_name = each.value.node_name
host = each.value.host
user = each.value.user
ssh_key_path = each.value.ssh_key_path
registry_endpoint = var.registry_endpoint
persistent_volume_dirs = join(",", var.persistent_volume_dirs)
}
connection {
type = "ssh"
user = self.triggers.user
private_key = file(self.triggers.ssh_key_path)
host = self.triggers.host
}
provisioner "remote-exec" {
inline = [
<<EOT
set -eu
sudo apt-get update
sudo apt-get install -y open-iscsi nfs-common
sudo systemctl enable --now iscsid
sudo systemctl enable --now kubelet || true
sudo mkdir -p /etc/containerd
if [ ! -f /etc/containerd/config.toml ]; then
sudo containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
fi
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo sed -i 's#config_path = ""#config_path = "/etc/containerd/certs.d"#' /etc/containerd/config.toml
sudo mkdir -p /etc/containerd/certs.d/${self.triggers.registry_endpoint}
sudo tee /etc/containerd/certs.d/${self.triggers.registry_endpoint}/hosts.toml >/dev/null <<REGISTRY_EOT
server = "http://${self.triggers.registry_endpoint}"
[host."http://${self.triggers.registry_endpoint}"]
capabilities = ["pull", "resolve", "push"]
skip_verify = true
REGISTRY_EOT
sudo systemctl restart containerd
pv_dirs="${self.triggers.persistent_volume_dirs}"
IFS=','
for path in $pv_dirs; do
sudo mkdir -p "$path"
sudo chmod 0775 "$path"
done
if [ ! -f /etc/kubernetes/kubelet.conf ]; then
sudo ${data.external.kubeadm_join_command.result.cmd} --node-name=${self.triggers.node_name}
fi
EOT
]
}
}
output "kubeconfig_path" {
value = var.kubeconfig_path
}
output "pod_network_cidr" {
value = var.pod_network_cidr
}