terraform-hcloud-kube-hetzner/init.tf
Marco Nenciarini 0c3aa36c03
First control plane node is not special anymore
The first control plane node is now identical to any other server
node. The cluster initialization happens once in two steps: first,
make sure that the k3s cluster is initialized and then apply our
configurations while the other nodes join. This change makes the
initialization more resilient and even faster than before.
2022-02-22 13:36:25 +01:00

160 lines
5.9 KiB
HCL

resource "null_resource" "first_control_plane" {
connection {
user = "root"
private_key = local.ssh_private_key
agent_identity = local.ssh_identity
host = module.control_planes[0].ipv4_address
}
# Generating k3s master config file
provisioner "file" {
content = yamlencode({
node-name = module.control_planes[0].name
token = random_password.k3s_token.result
cluster-init = true
disable-cloud-controller = true
disable = ["servicelb", "local-storage"]
flannel-iface = "eth1"
kubelet-arg = "cloud-provider=external"
node-ip = module.control_planes[0].private_ipv4_address
advertise-address = module.control_planes[0].private_ipv4_address
tls-san = module.control_planes[0].private_ipv4_address
node-taint = var.allow_scheduling_on_control_plane ? [] : ["node-role.kubernetes.io/master:NoSchedule"]
node-label = var.automatically_upgrade_k3s ? ["k3s_upgrade=true"] : []
})
destination = "/tmp/config.yaml"
}
# Install k3s server
provisioner "remote-exec" {
inline = local.install_k3s_server
}
# Upon reboot verify that the k3s server is starts, and wait for k3s to be ready to receive commands
provisioner "remote-exec" {
inline = [
"systemctl start k3s",
# prepare the post_install directory
"mkdir -p /tmp/post_install",
# wait for k3s to become ready
<<-EOT
timeout 120 bash <<EOF
until systemctl status k3s > /dev/null; do
systemctl start k3s
echo "Waiting for the k3s server to start..."
sleep 2
done
until [ -e /etc/rancher/k3s/k3s.yaml ]; do
echo "Waiting for kubectl config..."
sleep 2
done
until [[ "\$(kubectl get --raw='/readyz' 2> /dev/null)" == "ok" ]]; do
echo "Waiting for the cluster to become ready..."
sleep 2
done
EOF
EOT
]
}
depends_on = [
hcloud_network_subnet.k3s,
hcloud_firewall.k3s
]
}
resource "null_resource" "kustomization" {
connection {
user = "root"
private_key = local.ssh_private_key
agent_identity = local.ssh_identity
host = module.control_planes[0].ipv4_address
}
# Upload kustomization.yaml, containing Hetzner CSI & CSM, as well as kured.
provisioner "file" {
content = yamlencode({
apiVersion = "kustomize.config.k8s.io/v1beta1"
kind = "Kustomization"
resources = [
"https://github.com/hetznercloud/hcloud-cloud-controller-manager/releases/download/${local.ccm_version}/ccm-networks.yaml",
"https://raw.githubusercontent.com/hetznercloud/csi-driver/${local.csi_version}/deploy/kubernetes/hcloud-csi.yml",
"https://github.com/weaveworks/kured/releases/download/${local.kured_version}/kured-${local.kured_version}-dockerhub.yaml",
"https://raw.githubusercontent.com/rancher/system-upgrade-controller/master/manifests/system-upgrade-controller.yaml",
"traefik.yaml",
]
patchesStrategicMerge = [
file("${path.module}/kustomize/kured.yaml"),
file("${path.module}/kustomize/ccm.yaml"),
file("${path.module}/kustomize/system-upgrade-controller.yaml")
]
})
destination = "/tmp/post_install/kustomization.yaml"
}
# Upload traefik config
provisioner "file" {
content = templatefile(
"${path.module}/templates/traefik_config.yaml.tpl",
{
lb_disable_ipv6 = var.lb_disable_ipv6
lb_server_type = var.lb_server_type
location = var.location
traefik_acme_tls = var.traefik_acme_tls
traefik_acme_email = var.traefik_acme_email
})
destination = "/tmp/post_install/traefik.yaml"
}
# Upload the system upgrade controller plans config
provisioner "file" {
content = templatefile(
"${path.module}/templates/plans.yaml.tpl",
{
channel = var.k3s_upgrade_channel
})
destination = "/tmp/post_install/plans.yaml"
}
# Deploy secrets, logging is automatically disabled due to sensitive variables
provisioner "remote-exec" {
inline = [
"set -ex",
"kubectl -n kube-system create secret generic hcloud --from-literal=token=${var.hcloud_token} --from-literal=network=${hcloud_network.k3s.name}",
"kubectl -n kube-system create secret generic hcloud-csi --from-literal=token=${var.hcloud_token}",
]
}
# Deploy our post-installation kustomization
provisioner "remote-exec" {
inline = [
"set -ex",
# This ugly hack is here, because terraform serializes the
# embedded yaml files with "- |2", when there is more than
# one yamldocument in the embedded file. Kustomize does not understand
# that syntax and tries to parse the blocks content as a file, resulting
# in weird errors. so gnu sed with funny escaping is used to
# replace lines like "- |3" by "- |" (yaml block syntax).
# due to indendation this should not changes the embedded
# manifests themselves
"sed -i 's/^- |[0-9]\\+$/- |/g' /tmp/post_install/kustomization.yaml",
"kubectl apply -k /tmp/post_install",
"echo 'Waiting for the system-upgrade-controller deployment to become available...'",
"kubectl -n system-upgrade wait --for=condition=available --timeout=120s deployment/system-upgrade-controller",
"kubectl -n system-upgrade apply -f /tmp/post_install/plans.yaml",
<<-EOT
timeout 120 bash <<EOF
until [ -n "\$(kubectl get -n kube-system service/traefik --output=jsonpath='{.status.loadBalancer.ingress[0].ip}' 2> /dev/null)" ]; do
echo "Waiting for load-balancer to get an IP..."
sleep 2
done
EOF
EOT
]
}
depends_on = [
null_resource.first_control_plane
]
}