diff --git a/modules/hetzner/README.md b/modules/hetzner/README.md index 01e4eff..9497c7c 100644 --- a/modules/hetzner/README.md +++ b/modules/hetzner/README.md @@ -74,4 +74,5 @@ No modules. | [kubeconfig](#output\_kubeconfig) | Kubeconfig file | | [location](#output\_location) | Location to use. This is a single datacentre. | | [region](#output\_region) | Region to use. This covers multiple datacentres. | +| [worker\_pools](#output\_worker\_pools) | Worker pool configuration for Cluster Autoscaler | diff --git a/modules/hetzner/output.tf b/modules/hetzner/output.tf index 3a72f8f..7d45a96 100644 --- a/modules/hetzner/output.tf +++ b/modules/hetzner/output.tf @@ -43,3 +43,60 @@ output "region" { description = "Region to use. This covers multiple datacentres." value = var.region } + +output "worker_pools" { + sensitive = true + description = "Worker pool configuration for Cluster Autoscaler" + value = [ + for w in var.k3s_worker_pools : { + firewall_id = hcloud_firewall.name.id + network_id = hcloud_network.network.id + ssh_key_id = hcloud_ssh_key.server.id + pool = { + instanceType = w.server_type + minSize = w.autoscaling.min + maxSize = w.autoscaling.max + name = w.name + region = w.location != null ? w.location : var.location + } + config = { + imagesForArch = { + arm64 = "ubuntu-24.04" + amd64 = "ubuntu-24.04" + } + nodeConfigs = { + (w.name) = { + cloudInit = templatefile("${path.module}/files/k3s-worker.yaml", { + k3s_config = { + # node-label = [for l in w.labels : "${l.key}=${l.value}"] + # node-taint = [for t in local.k3s_worker_nodes[count.index].taints : "${t.key}=${t.value}:${t.effect}"] + server = local.k3s_server_url + token = local.k3s_join_token + } + k3s_download_url = var.k3s_download_url + sshPort = var.ssh_port + publicKey = hcloud_ssh_key.server.public_key + user = local.machine_user + }) + labels = merge( + { + "node.kubernetes.io/role" = "autoscaler-node", + format(local.label_namespace, "pool") = w.name + }, + { for l in w.labels : l.key => l.value } + ) + taints = concat([ + { + key = "node.kubernetes.io/role", + value = "autoscaler-node", + effect = "NoExecute" + } + ], + w.taints, + ) + } + } + } + } if lookup(w.autoscaling, "enabled", false) == true + ] +} diff --git a/modules/kubernetes/README.md b/modules/kubernetes/README.md index 1a3aaa5..ab393f8 100644 --- a/modules/kubernetes/README.md +++ b/modules/kubernetes/README.md @@ -25,9 +25,12 @@ No modules. | Name | Type | |------|------| | [helm_release.cilium](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | +| [helm_release.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.hcloud_ccm](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [helm_release.hcloud_csi](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [kubernetes_annotations.hcloud_ccm](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/annotations) | resource | +| [kubernetes_namespace.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | +| [kubernetes_secret_v1.cluster_autoscaler](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret_v1) | resource | | [kubernetes_secret_v1.hcloud](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret_v1) | resource | ## Inputs @@ -35,6 +38,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [cilium\_version](#input\_cilium\_version) | Version of Cilium to use - defaults to latest | `string` | `null` | no | +| [cluster\_autoscaler\_version](#input\_cluster\_autoscaler\_version) | Version of Cluster Autoscaler to use - defaults to latest | `string` | `null` | no | | [hcloud\_network\_name](#input\_hcloud\_network\_name) | Hetzner network name | `string` | n/a | yes | | [hcloud\_token](#input\_hcloud\_token) | Hetzner API token | `string` | n/a | yes | | [hetzner\_cloud\_config\_manager\_version](#input\_hetzner\_cloud\_config\_manager\_version) | Version of the HCloud CCM to use - defaults to latest | `string` | `null` | no | @@ -42,6 +46,7 @@ No modules. | [k3s\_cluster\_cidr](#input\_k3s\_cluster\_cidr) | CIDR used for the k3s cluster | `string` | `"10.244.0.0/16"` | no | | [kube\_context](#input\_kube\_context) | Kubernetes context to use | `string` | `"default"` | no | | [kubeconfig](#input\_kubeconfig) | Kubeconfig for the cluster | `string` | n/a | yes | +| [worker\_pools](#input\_worker\_pools) | Cluster autoscaler configuration |
list(object({| `[]` | no | ## Outputs diff --git a/modules/kubernetes/autoscaler.tf b/modules/kubernetes/autoscaler.tf new file mode 100644 index 0000000..1fe24e3 --- /dev/null +++ b/modules/kubernetes/autoscaler.tf @@ -0,0 +1,82 @@ +# Copyright 2024 Simon Emms
firewall_id = string
network_id = string
ssh_key_id = string
pool = object({
instanceType = string
minSize = number
maxSize = number
name = string
region = string
})
config = object({
imagesForArch = object({
arm64 = string
amd64 = string
})
nodeConfigs = map(object({
cloudInit = string
labels = map(string)
taints = list(object({
key = string
value = string
effect = string
}))
}))
})
}))