diff --git a/.gitignore b/.gitignore index 5f02e99..6c2542f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ kubeconfig.yaml-e terraform.tfvars plans-custom.yaml traefik-custom.yaml -kured-custom.yaml \ No newline at end of file +kured-custom.yaml diff --git a/agents.tf b/agents.tf index 3e23079..a8e5423 100644 --- a/agents.tf +++ b/agents.tf @@ -3,7 +3,7 @@ module "agents" { for_each = local.agent_nodepools - name = each.key + name = "${var.use_cluster_name_in_node_name ? "${random_pet.cluster.id}-" : ""}${each.value.nodepool_name}" ssh_keys = [hcloud_ssh_key.k3s.id] public_key = var.public_key private_key = var.private_key @@ -23,8 +23,6 @@ module "agents" { "engine" = "k3s" } - hcloud_token = var.hcloud_token - depends_on = [ hcloud_network_subnet.subnet ] diff --git a/control_planes.tf b/control_planes.tf index 440dc3a..e3130c4 100644 --- a/control_planes.tf +++ b/control_planes.tf @@ -1,9 +1,8 @@ module "control_planes" { source = "./modules/host" - count = var.control_plane_count - name = "control-plane-${count.index}" - + count = var.control_plane_count + name = "${var.use_cluster_name_in_node_name ? "${random_pet.cluster.id}-" : ""}control-plane" ssh_keys = [hcloud_ssh_key.k3s.id] public_key = var.public_key private_key = var.private_key @@ -23,8 +22,6 @@ module "control_planes" { "engine" = "k3s" } - hcloud_token = var.hcloud_token - depends_on = [ hcloud_network_subnet.subnet ] diff --git a/init.tf b/init.tf index 3c73029..e07bc45 100644 --- a/init.tf +++ b/init.tf @@ -94,6 +94,7 @@ resource "null_resource" "kustomization" { content = local.is_single_node_cluster ? "" : templatefile( "${path.module}/templates/traefik_config.yaml.tpl", { + name = "${random_pet.cluster.id}-traefik" load_balancer_disable_ipv6 = var.load_balancer_disable_ipv6 load_balancer_type = var.load_balancer_type location = var.location diff --git a/locals.tf b/locals.tf index 595cf45..a01b5cd 100644 --- a/locals.tf +++ b/locals.tf @@ -173,6 +173,7 @@ locals { for nodepool_name, nodepool_obj in var.agent_nodepools : { for index in range(nodepool_obj.count) : format("%s-%s", nodepool_name, index) => { + nodepool_name : nodepool_name, server_type : nodepool_obj.server_type, subnet : nodepool_obj.subnet, index : index diff --git a/main.tf b/main.tf index ae01da9..b78a41d 100644 --- a/main.tf +++ b/main.tf @@ -1,15 +1,20 @@ +resource "random_pet" "cluster" { + length = 1 + prefix = var.cluster_prefix +} + resource "random_password" "k3s_token" { length = 48 special = false } resource "hcloud_ssh_key" "k3s" { - name = "k3s" + name = random_pet.cluster.id public_key = local.ssh_public_key } resource "hcloud_network" "k3s" { - name = "k3s" + name = random_pet.cluster.id ip_range = var.network_ipv4_range } @@ -32,7 +37,7 @@ resource "hcloud_network_subnet" "subnet" { } resource "hcloud_firewall" "k3s" { - name = "k3s" + name = random_pet.cluster.id dynamic "rule" { for_each = concat(local.base_firewall_rules, var.extra_firewall_rules) @@ -47,7 +52,7 @@ resource "hcloud_firewall" "k3s" { } resource "hcloud_placement_group" "k3s" { - name = "k3s" + name = random_pet.cluster.id type = "spread" labels = { "provisioner" = "terraform", @@ -57,7 +62,7 @@ resource "hcloud_placement_group" "k3s" { data "hcloud_load_balancer" "traefik" { count = local.is_single_node_cluster ? 0 : 1 - name = "traefik" + name = "${random_pet.cluster.id}-traefik" depends_on = [null_resource.kustomization] } diff --git a/modules/host/locals.tf b/modules/host/locals.tf index 1fcef4d..46e0f81 100644 --- a/modules/host/locals.tf +++ b/modules/host/locals.tf @@ -10,4 +10,7 @@ locals { ssh_identity_file = var.private_key == null ? var.public_key : var.private_key # shared flags for ssh to ignore host keys, to use our ssh identity file for all connections during provisioning. ssh_args = "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ${local.ssh_identity_file}" + + # the hosts name with its unique suffix attached + name = "${var.name}-${random_pet.server.id}" } diff --git a/modules/host/main.tf b/modules/host/main.tf index e085883..e397391 100644 --- a/modules/host/main.tf +++ b/modules/host/main.tf @@ -1,5 +1,25 @@ +resource "random_pet" "server" { + length = 1 + keepers = { + # We re-create the id (and server) whenever one of those attributes + # changes. This should include all input variables to this module, + # but NO SENSITIVE values as they might be logged here. + name = var.name + public_key = var.public_key + additional_public_keys = join(",", var.additional_public_keys) + ssh_keys = join(",", var.ssh_keys) + firewall_ids = join(",", var.firewall_ids) + placement_group_id = var.placement_group_id + labels = join(",", [for k, v in var.labels: "${k}=${v}" ]) + location = var.location + ipv4_subnet_id = var.ipv4_subnet_id + private_ipv4 = var.private_ipv4 + server_type = var.server_type + } +} + resource "hcloud_server" "server" { - name = var.name + name = local.name image = "ubuntu-20.04" rescue = "linux64" @@ -90,7 +110,7 @@ data "template_cloudinit_config" "config" { content = templatefile( "${path.module}/templates/userdata.yaml.tpl", { - hostname = var.name + hostname = local.name sshAuthorizedKeys = concat([local.ssh_public_key], var.additional_public_keys) } ) diff --git a/modules/host/variables.tf b/modules/host/variables.tf index 01abaa6..a8a454e 100644 --- a/modules/host/variables.tf +++ b/modules/host/variables.tf @@ -1,9 +1,3 @@ -variable "hcloud_token" { - description = "Hetzner Cloud API Token" - type = string - sensitive = true -} - variable "name" { description = "Host name" type = string diff --git a/output.tf b/output.tf index 4d2033e..9337e1d 100644 --- a/output.tf +++ b/output.tf @@ -1,3 +1,8 @@ +output "cluster_name" { + value = random_pet.cluster.id + description = "Shared suffix for all resources belonging to this cluster." +} + output "control_planes_public_ipv4" { value = module.control_planes.*.ipv4_address description = "The public IPv4 addresses of the controlplane server." diff --git a/templates/traefik_config.yaml.tpl b/templates/traefik_config.yaml.tpl index 05fc68d..03fd6e7 100644 --- a/templates/traefik_config.yaml.tpl +++ b/templates/traefik_config.yaml.tpl @@ -9,7 +9,7 @@ spec: enabled: true type: LoadBalancer annotations: - "load-balancer.hetzner.cloud/name": "traefik" + "load-balancer.hetzner.cloud/name": ${name} # make hetzners load-balancer connect to our nodes via our private k3s "load-balancer.hetzner.cloud/use-private-ip": "true" # keep hetzner-ccm from exposing our private ingress ip, which in general isn't routeable from the public internet @@ -31,4 +31,4 @@ spec: - "--certificatesresolvers.le.acme.tlschallenge=true" - "--certificatesresolvers.le.acme.email=${traefik_acme_email}" - "--certificatesresolvers.le.acme.storage=/data/acme.json" -%{ endif ~} \ No newline at end of file +%{ endif ~} diff --git a/terraform.tfvars.example b/terraform.tfvars.example index 41e9484..1688b31 100644 --- a/terraform.tfvars.example +++ b/terraform.tfvars.example @@ -77,6 +77,12 @@ load_balancer_type = "lb11" # Allows you to specify either stable, latest, or testing (defaults to stable), see https://rancher.com/docs/k3s/latest/en/upgrades/basic/ # initial_k3s_channel = "latest" +# Whether to use the cluster name in the node name, i.e. add the prefix k3s-(cluster_name)- to the nodes? The default is "true". +# use_cluster_name_in_node_name = false + +# Prefix for the cluster name, by default "k3s" +# cluster_prefix = "" + # Adding extra firewall rules, like opening a port # In this example with allow port TCP 5432 for a Postgres service we will open via a nodeport # More info on the format here https://registry.terraform.io/providers/hetznercloud/hcloud/latest/docs/resources/firewall diff --git a/variables.tf b/variables.tf index b299dea..49d0e51 100644 --- a/variables.tf +++ b/variables.tf @@ -121,7 +121,20 @@ variable "extra_firewall_rules" { description = "Additional firewall rules to apply to the cluster" } +variable "use_cluster_name_in_node_name" { + type = bool + default = true + description = "Whether to use the cluster name in the node name" +} + +variable "cluster_prefix" { + type = string + default = "k3s" + description = "Prefix for the cluster name" +} + variable "traefik_additional_options" { type = list(string) default = [] + }