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 = </dev/null | grep -q "install ok installed"; then missing_packages="$missing_packages $package" fi done if [ -n "$missing_packages" ]; then sudo apt-get update sudo apt-get install -y --no-install-recommends $missing_packages fi } install_missing_packages open-iscsi nfs-common sudo systemctl enable --now iscsid sudo systemctl enable kubelet || true sudo swapoff -a || true sudo awk ' /^[[:space:]]*#/ { print; next } $3 == "swap" { print "# kubeadm-disabled " $0; next } { print } ' /etc/fstab | sudo tee /etc/fstab.kubeadm >/dev/null sudo mv /etc/fstab.kubeadm /etc/fstab sudo tee /etc/modules-load.d/k8s.conf >/dev/null <<'MODULES_EOT' overlay br_netfilter MODULES_EOT sudo modprobe overlay || true sudo modprobe br_netfilter || true sudo tee /etc/sysctl.d/99-kubernetes-cri.conf >/dev/null <<'SYSCTL_EOT' net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 SYSCTL_EOT sudo sysctl -w net.ipv4.ip_forward=1 >/dev/null if [ -e /proc/sys/net/bridge/bridge-nf-call-iptables ]; then sudo sysctl -w net.bridge.bridge-nf-call-iptables=1 >/dev/null sudo sysctl -w net.bridge.bridge-nf-call-ip6tables=1 >/dev/null fi if ! getent hosts "${self.triggers.node_name}" >/dev/null; then printf '%s %s\n' "${self.triggers.advertise_address}" "${self.triggers.node_name}" | sudo tee -a /etc/hosts >/dev/null fi 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 </dev/null || true sudo rm -rf /etc/kubernetes/ /var/lib/etcd/ /var/lib/kubelet/ /var/lib/cni/ /etc/cni/net.d fi if [ ! -f /etc/kubernetes/admin.conf ]; then sudo systemctl stop kubelet 2>/dev/null || true if ! sudo kubeadm init \ --pod-network-cidr=${self.triggers.pod_network_cidr} \ --node-name=${self.triggers.node_name} \ --apiserver-advertise-address=${self.triggers.advertise_address}; then sudo systemctl status kubelet --no-pager -l || true sudo journalctl -u kubelet --no-pager -n 160 || true exit 1 fi 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", </dev/null | grep -q "install ok installed"; then missing_packages="$missing_packages $package" fi done if [ -n "$missing_packages" ]; then sudo apt-get update sudo apt-get install -y --no-install-recommends $missing_packages fi } install_missing_packages open-iscsi nfs-common sudo systemctl enable --now iscsid sudo systemctl enable kubelet || true sudo swapoff -a || true sudo awk ' /^[[:space:]]*#/ { print; next } $3 == "swap" { print "# kubeadm-disabled " $0; next } { print } ' /etc/fstab | sudo tee /etc/fstab.kubeadm >/dev/null sudo mv /etc/fstab.kubeadm /etc/fstab sudo tee /etc/modules-load.d/k8s.conf >/dev/null <<'MODULES_EOT' overlay br_netfilter MODULES_EOT sudo modprobe overlay || true sudo modprobe br_netfilter || true sudo tee /etc/sysctl.d/99-kubernetes-cri.conf >/dev/null <<'SYSCTL_EOT' net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 SYSCTL_EOT sudo sysctl -w net.ipv4.ip_forward=1 >/dev/null if [ -e /proc/sys/net/bridge/bridge-nf-call-iptables ]; then sudo sysctl -w net.bridge.bridge-nf-call-iptables=1 >/dev/null sudo sysctl -w net.bridge.bridge-nf-call-ip6tables=1 >/dev/null fi if ! getent hosts "${self.triggers.node_name}" >/dev/null; then printf '%s %s\n' "${self.triggers.host}" "${self.triggers.node_name}" | sudo tee -a /etc/hosts >/dev/null fi 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 </dev/tcp/127.0.0.1/10248; printf "GET /healthz HTTP/1.0\r\n\r\n" >&3; grep -q ok <&3' >/dev/null 2>&1; then sudo kubeadm reset --force || true sudo systemctl stop kubelet 2>/dev/null || true sudo rm -rf /etc/kubernetes/ /var/lib/kubelet/ /var/lib/cni/ /etc/cni/net.d fi if [ ! -f /etc/kubernetes/kubelet.conf ] && [ -e /var/lib/kubelet/kubeadm-flags.env ]; then sudo kubeadm reset --force || true sudo systemctl stop kubelet 2>/dev/null || true sudo rm -rf /etc/kubernetes/ /var/lib/kubelet/ /var/lib/cni/ /etc/cni/net.d fi if [ ! -f /etc/kubernetes/kubelet.conf ]; then sudo systemctl stop kubelet 2>/dev/null || true if ! sudo ${data.external.kubeadm_join_command.result.cmd} --node-name=${self.triggers.node_name}; then sudo systemctl status kubelet --no-pager -l || true sudo journalctl -u kubelet --no-pager -n 160 || true exit 1 fi fi EOT ] } } output "kubeconfig_path" { value = var.kubeconfig_path } output "pod_network_cidr" { value = var.pod_network_cidr }