I'm trying to bootstrap a HA Kubernetes cluster with terraform and hetzner cloud provider. In my setup the loadbalancer in front of the control plane nodes needs to know the ip addresses of the master nodes in the cluster. This is so that i can register the master nodes as targets for the loadbalancer.
Similarly, when bootstrapping the master nodes, knowledge of the loadbalancer ip address is required to populate their configuration.
I could use a dns name inside the masters configuration and later create the association between lb ip and name but I wanted to avoid using dns names. Is there some other way of achiving this result?
For some context here is an extract from my code :
resource "hcloud_load_balancer" "cluster-lb" {
name = "my-load-balancer"
load_balancer_type = "lb11"
location = "nbg1"
dynamic "target" {
for_each = var.master_node_ids # this is an input parameter
content { # that requires the master servers to exist.
type = "server"
server_id = target.value["id"]
}
}
}
locals {
# Here I must crate both a InitConfiguration and a ClusterConfiguration. These config files are used
# by kubeadm to bootstrap the cluster. Among other things, ClusterConfiguration requires the
# controlPlaneEndpoint argument to be specified. This represents the shared endpoint to access the
# cluster. In a HA scenario it is the ip address of the loadbalancer.
kubeadm_init = templatefile(
"kubeadm_init.tmpl",
{
controlPlaneEndpoint = ???
}
}
# Later on the kubeadm_init is incorporated in a cloud-init write_files attribute so it is copied to
# the server. I've omitted this section as it is quite verbose and not really useful in answering the
# question. If necessary i can provide it as well.
# Here I create the master nodes :
resource "hcloud_server" "cluster-masters" {
for_each = local.masters
name = "server-${each.key}"
server_type = "cpx11"
image = "ubuntu-20.04"
location = each.value["availability_zone"]
user_data = local.cloud_init_data
network {
network_id = var.network_id
ip = each.value["ip"]
}
}
Seems to me that there is a cyclic dependency between the cluster loadbalancer and the server. The first one must await the creation of the master nodes so to add them as targets. The master nodes on the other hand must await the loadbalancer in order to get its ip and populate their configuration files before beeing created. How could I go solving this issue and is it an actual issue in the first place?
Thanks in advance to everyone and let me know how to improve my question!
Create hcloud_load_balancer cluster-lb resource without optional target list https://registry.terraform.io/providers/hetznercloud/hcloud/latest/docs/resources/load_balancer#target
Use hcloud_load_balancer.cluster-lb.ipv4 for controlPlaneEndpoint https://registry.terraform.io/providers/hetznercloud/hcloud/latest/docs/resources/load_balancer#ipv4
Create hcloud_load_balancer_target resource with type = label_selector and load_balancer_id = hcloud_load_balancer.cluster-lb.id and label_selector = hcloud_server.cluster-masters.labels https://registry.terraform.io/providers/hetznercloud/hcloud/latest/docs/resources/load_balancer_target
I suggest to use some existing Terraform Module for deploying Kubernetes on Hetzner Cloud.