feat(tofu): updated kubernetes setup

tried to to some tidying while writing an article based on the current
setup.
This commit is contained in:
Vegard Hagen
2024-08-03 13:32:43 +02:00
parent 0a265cbfd5
commit c4ba7120dd
19 changed files with 211 additions and 234 deletions

View File

@@ -41,19 +41,19 @@ kubectl -n argocd get secret argocd-initial-admin-secret -ojson | jq -r ' .data.
``` ```
```shell ```shell
kubectl kustomize infra | kubectl apply -f - kubectl apply -k sets
``` ```
# SBOM # SBOM
* [x] Cilium * [x] Cilium
* [] Hubble * [X] Hubble
* [x] Argo CD * [x] Argo CD
* [x] Proxmox CSI Plugin * [x] Proxmox CSI Plugin
* [x] Cert-manager * [x] Cert-manager
* [X] Gateway * [X] Gateway
* [] CNPG * [X] Authentication (Keycloak, Authentik, ...)
* [] Authentication (Keycloak, Authentik, ...) * [] CNPG - Cloud Native PostGresSQL
# CRDs # CRDs
@@ -63,13 +63,11 @@ kubectl kustomize infra | kubectl apply -f -
# TODO # TODO
* [] Remotely managed cloudflared tunnel * [X] Remotely managed cloudflared tunnel
* [] Keycloak * [X] Keycloak
* [] Argo CD sync-wave * [] Argo CD sync-wave
```shell ```shell
commonAnnotations: commonAnnotations:
argocd.argoproj.io/sync-wave: "-1" argocd.argoproj.io/sync-wave: "-1"
``` ```
CNPG - Cloud Native PostGresSQL

View File

@@ -4,4 +4,4 @@ variable "proxmox" {
endpoint = string endpoint = string
insecure = bool insecure = bool
}) })
} }

View File

@@ -17,7 +17,7 @@ resource "kubernetes_secret" "sealed-secrets-key" {
} }
data = { data = {
"tls.crt" = var.sealed_secrets_cert.cert "tls.crt" = var.cert.cert
"tls.key" = var.sealed_secrets_cert.key "tls.key" = var.cert.key
} }
} }

View File

@@ -1,4 +1,4 @@
variable "sealed_secrets_cert" { variable "cert" {
type = object({ type = object({
cert = string cert = string
key = string key = string

View File

@@ -28,10 +28,10 @@ tofu state rm "module.volumes.module.proxmox-volume[\"pv-jellyfin-config\"].rest
tofu state rm "module.volumes.module.proxmox-volume[\"pv-qbittorrent-config\"].restapi_object.proxmox-volume" tofu state rm "module.volumes.module.proxmox-volume[\"pv-qbittorrent-config\"].restapi_object.proxmox-volume"
``` ```
## import ## import proxmox volume
```shell ```shell
tofu import "module.volumes.module.proxmox-volume[\"pv-lidarr-config\"].restapi_object.proxmox-volume" /api2/json/nodes/cantor/storage/local-zfs/content/local-zfs:vm-9999-pv-lidarr-config tofu import 'module.volumes.module.proxmox-volume["pv-lidarr-config"].restapi_object.proxmox-volume' /api2/json/nodes/cantor/storage/local-zfs/content/local-zfs:vm-9999-pv-lidarr-config
tofu import "module.volumes.module.proxmox-volume[\"pv-radarr-config\"].restapi_object.proxmox-volume" /api2/json/nodes/cantor/storage/local-zfs/content/local-zfs:vm-9999-pv-radarr-config tofu import "module.volumes.module.proxmox-volume[\"pv-radarr-config\"].restapi_object.proxmox-volume" /api2/json/nodes/cantor/storage/local-zfs/content/local-zfs:vm-9999-pv-radarr-config
tofu import "module.volumes.module.proxmox-volume[\"pv-sonarr-config\"].restapi_object.proxmox-volume" /api2/json/nodes/cantor/storage/local-zfs/content/local-zfs:vm-9999-pv-sonarr-config tofu import "module.volumes.module.proxmox-volume[\"pv-sonarr-config\"].restapi_object.proxmox-volume" /api2/json/nodes/cantor/storage/local-zfs/content/local-zfs:vm-9999-pv-sonarr-config
@@ -39,4 +39,11 @@ tofu import "module.volumes.module.proxmox-volume[\"pv-qbittorrent-config\"].res
tofu import "module.volumes.module.proxmox-volume[\"pv-plex-config\"].restapi_object.proxmox-volume" /api2/json/nodes/abel/storage/local-zfs/content/local-zfs:vm-9999-pv-plex-config tofu import "module.volumes.module.proxmox-volume[\"pv-plex-config\"].restapi_object.proxmox-volume" /api2/json/nodes/abel/storage/local-zfs/content/local-zfs:vm-9999-pv-plex-config
tofu import "module.volumes.module.proxmox-volume[\"pv-jellyfin-config\"].restapi_object.proxmox-volume" /api2/json/nodes/abel/storage/local-zfs/content/local-zfs:vm-9999-pv-jellyfin-config tofu import "module.volumes.module.proxmox-volume[\"pv-jellyfin-config\"].restapi_object.proxmox-volume" /api2/json/nodes/abel/storage/local-zfs/content/local-zfs:vm-9999-pv-jellyfin-config
```
## import persistent volume
```shell
tofu import 'module.volumes.module.persistent-volume["pv-torrent-config"].kubernetes_persistent_volume.pv' pv-torrent-config
``` ```

View File

@@ -1,21 +0,0 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: plex-config
spec:
storageClassName: proxmox-csi
accessModes:
- ReadWriteOnce
capacity:
storage: 12Gi
csi:
driver: csi.proxmox.sinextra.dev
fsType: ext4
volumeAttributes:
cache: writethrough
ssd: "true"
storage: local-zfs
volumeHandle: homelab/abel/local-zfs/vm-9999-plex-config
mountOptions:
- noatime
volumeMode: Filesystem

View File

@@ -5,65 +5,74 @@ module "talos" {
proxmox = proxmox proxmox = proxmox
} }
talos_image = { image = {
version = "v1.7.5" version = "v1.7.5"
schematic = file("${path.module}/config/talos-image-schematic.yaml") schematic = file("${path.module}/talos/image/schematic.yaml")
} }
cilium = { cilium = {
values = file("${path.module}/../../k8s/infra/network/cilium/values.yaml") values = file("${path.module}/../../k8s/infra/network/cilium/values.yaml")
install = file("${path.module}/bootstrap/cilium/install.yaml") install = file("${path.module}/talos/inline-manifests/cilium-install.yaml")
} }
cluster_config = { cluster = {
cluster_name = "talos" name = "talos"
proxmox_cluster = "homelab" endpoint = "192.168.1.100"
endpoint = "https://192.168.1.100:6443" gateway = "192.168.1.1"
talos_version = "v1.7" talos_version = "v1.7"
nodes = { proxmox_cluster = "homelab"
"ctrl-00" = { }
machine_type = "controlplane"
ip = "192.168.1.100" nodes = {
mac_address = "BC:24:11:2E:C8:00" "ctrl-00" = {
host_node = "abel" host_node = "abel"
vm_id = 8000 machine_type = "controlplane"
cpu = 8 ip = "192.168.1.100"
ram_dedicated = 20480 mac_address = "BC:24:11:2E:C8:00"
igpu = true vm_id = 8000
} cpu = 8
"ctrl-01" = { ram_dedicated = 20480
host_node = "euclid" igpu = true
machine_type = "controlplane" update = true
ip = "192.168.1.101" }
mac_address = "BC:24:11:2E:C8:01" "ctrl-01" = {
vm_id = 8001 host_node = "euclid"
cpu = 4 machine_type = "controlplane"
ram_dedicated = 20480 ip = "192.168.1.101"
igpu = true mac_address = "BC:24:11:2E:C8:01"
} vm_id = 8001
"ctrl-02" = { cpu = 4
host_node = "cantor" ram_dedicated = 20480
machine_type = "controlplane" igpu = true
ip = "192.168.1.102" }
mac_address = "BC:24:11:2E:C8:02" "ctrl-02" = {
vm_id = 8002 host_node = "cantor"
cpu = 4 machine_type = "controlplane"
ram_dedicated = 4096 ip = "192.168.1.102"
} mac_address = "BC:24:11:2E:C8:02"
//"work-00" = { vm_id = 8002
// host_node = "abel" cpu = 4
// machine_type = "worker" ram_dedicated = 4096
// ip = "192.168.1.110"
// mac_address = "BC:24:11:2E:08:00"
// vm_id = 8100
// cpu = 8
// ram_dedicated = 4096
//}
} }
} }
} }
module "sealed_secrets" {
depends_on = [module.talos]
source = "./bootstrap/sealed-secrets"
providers = {
kubernetes = kubernetes
}
// openssl req -x509 -days 365 -nodes -newkey rsa:4096 -keyout sealed-secrets.key -out sealed-secrets.cert -subj "/CN=sealed-secret/O=sealed-secret"
cert = {
cert = file("${path.module}/bootstrap/sealed-secrets/certificate/sealed-secrets.cert")
key = file("${path.module}/bootstrap/sealed-secrets/certificate/sealed-secrets.key")
}
}
module "proxmox_csi_plugin" { module "proxmox_csi_plugin" {
depends_on = [module.talos] depends_on = [module.talos]
source = "./bootstrap/proxmox-csi-plugin" source = "./bootstrap/proxmox-csi-plugin"
@@ -76,21 +85,6 @@ module "proxmox_csi_plugin" {
proxmox = var.proxmox proxmox = var.proxmox
} }
module "sealed_secrets" {
depends_on = [module.talos]
source = "./bootstrap/sealed-secrets"
providers = {
kubernetes = kubernetes
}
// openssl req -x509 -days 365 -nodes -newkey rsa:4096 -keyout sealed-secrets.key -out sealed-secrets.cert -subj "/CN=sealed-secret/O=sealed-secret"
sealed_secrets_cert = {
cert = file("${path.module}/config/sealed-secrets.cert")
key = file("${path.module}/config/sealed-secrets.key")
}
}
module "volumes" { module "volumes" {
depends_on = [module.proxmox_csi_plugin] depends_on = [module.proxmox_csi_plugin]
source = "./bootstrap/volumes" source = "./bootstrap/volumes"

View File

@@ -1,28 +1,28 @@
resource "local_file" "machine_configs" { resource "local_file" "machine_configs" {
for_each = module.talos.talos_machine_config for_each = module.talos.machine_config
content = each.value.machine_configuration content = each.value.machine_configuration
filename = "output/talos-machine-config-${each.key}.yaml" filename = "output/talos-machine-config-${each.key}.yaml"
file_permission = "0600" file_permission = "0600"
} }
resource "local_file" "talos_config" { resource "local_file" "talos_config" {
content = module.talos.talos_client_configuration.talos_config content = module.talos.client_configuration.talos_config
filename = "output/talos-config.yaml" filename = "output/talos-config.yaml"
file_permission = "0600" file_permission = "0600"
} }
resource "local_file" "kube_config" { resource "local_file" "kube_config" {
content = module.talos.talos_kube_config.kubeconfig_raw content = module.talos.kube_config.kubeconfig_raw
filename = "output/kube-config.yaml" filename = "output/kube-config.yaml"
file_permission = "0600" file_permission = "0600"
} }
output "kube_config" { output "kube_config" {
value = module.talos.talos_kube_config.kubeconfig_raw value = module.talos.kube_config.kubeconfig_raw
sensitive = true sensitive = true
} }
output "talos_config" { output "talos_config" {
value = module.talos.talos_client_configuration.talos_config value = module.talos.client_configuration.talos_config
sensitive = true sensitive = true
} }

View File

@@ -42,12 +42,8 @@ provider "restapi" {
} }
provider "kubernetes" { provider "kubernetes" {
host = module.talos.talos_kube_config.kubernetes_client_configuration.host host = module.talos.kube_config.kubernetes_client_configuration.host
client_certificate = base64decode(module.talos.talos_kube_config.kubernetes_client_configuration.client_certificate) client_certificate = base64decode(module.talos.kube_config.kubernetes_client_configuration.client_certificate)
client_key = base64decode(module.talos.talos_kube_config.kubernetes_client_configuration.client_key) client_key = base64decode(module.talos.kube_config.kubernetes_client_configuration.client_key)
cluster_ca_certificate = base64decode(module.talos.talos_kube_config.kubernetes_client_configuration.ca_certificate) cluster_ca_certificate = base64decode(module.talos.kube_config.kubernetes_client_configuration.ca_certificate)
# ignore_labels = [
# "app.kubernetes.io/.*",
# "kustomize.toolkit.fluxcd.io/.*",
# ]
} }

View File

@@ -0,0 +1,79 @@
resource "talos_machine_secrets" "this" {
talos_version = var.cluster.talos_version
}
data "talos_client_configuration" "this" {
cluster_name = var.cluster.name
client_configuration = talos_machine_secrets.this.client_configuration
nodes = [for k, v in var.nodes : v.ip]
endpoints = [for k, v in var.nodes : v.ip if v.machine_type == "controlplane"]
}
data "talos_machine_configuration" "this" {
for_each = var.nodes
cluster_name = var.cluster.name
cluster_endpoint = "https://${var.cluster.endpoint}:6443"
talos_version = var.cluster.talos_version
machine_type = each.value.machine_type
machine_secrets = talos_machine_secrets.this.machine_secrets
config_patches = each.value.machine_type == "controlplane" ? [
templatefile("${path.module}/machine-config/control-plane.yaml.tftpl", {
hostname = each.key
node_name = each.value.host_node
cluster_name = var.cluster.proxmox_cluster
cilium_values = var.cilium.values
cilium_install = var.cilium.install
})
] : [
templatefile("${path.module}/machine-config/worker.yaml.tftpl", {
hostname = each.key
node_name = each.value.host_node
cluster_name = var.cluster.proxmox_cluster
})
]
}
resource "talos_machine_configuration_apply" "this" {
depends_on = [proxmox_virtual_environment_vm.this]
for_each = var.nodes
node = each.value.ip
client_configuration = talos_machine_secrets.this.client_configuration
machine_configuration_input = data.talos_machine_configuration.this[each.key].machine_configuration
lifecycle {
# re-run config apply if vm changes
replace_triggered_by = [proxmox_virtual_environment_vm.this[each.key]]
}
}
resource "talos_machine_bootstrap" "this" {
node = [for k, v in var.nodes : v.ip if v.machine_type == "controlplane"][0]
endpoint = var.cluster.endpoint
client_configuration = talos_machine_secrets.this.client_configuration
}
data "talos_cluster_health" "this" {
depends_on = [
talos_machine_configuration_apply.this,
talos_machine_bootstrap.this
]
client_configuration = data.talos_client_configuration.this.client_configuration
control_plane_nodes = [for k, v in var.nodes : v.ip if v.machine_type == "controlplane"]
worker_nodes = [for k, v in var.nodes : v.ip if v.machine_type == "worker"]
endpoints = data.talos_client_configuration.this.endpoints
timeouts = {
read = "10m"
}
}
data "talos_cluster_kubeconfig" "this" {
depends_on = [
talos_machine_bootstrap.this,
data.talos_cluster_health.this
]
node = [for k, v in var.nodes : v.ip if v.machine_type == "controlplane"][0]
endpoint = var.cluster.endpoint
client_configuration = talos_machine_secrets.this.client_configuration
timeouts = {
read = "1m"
}
}

View File

@@ -1,38 +1,36 @@
locals { locals {
version = var.talos_image.version version = var.image.version
schematic = var.talos_image.schematic schematic = var.image.schematic
schematic_id = jsondecode(data.http.schematic_id.response_body)["id"] schematic_id = jsondecode(data.http.schematic_id.response_body)["id"]
url = "${var.talos_image.factory_url}/image/${local.schematic_id}/${local.version}/${var.talos_image.platform}-${var.talos_image.arch}.raw.gz"
image_id = "${local.schematic_id}_${local.version}" image_id = "${local.schematic_id}_${local.version}"
update_version = coalesce(var.talos_image.update_version, var.talos_image.version) update_version = coalesce(var.image.update_version, var.image.version)
update_schematic = coalesce(var.talos_image.update_schematic, var.talos_image.schematic) update_schematic = coalesce(var.image.update_schematic, var.image.schematic)
update_schematic_id = jsondecode(data.http.updated_schematic_id.response_body)["id"] update_schematic_id = jsondecode(data.http.updated_schematic_id.response_body)["id"]
update_url = "${var.talos_image.factory_url}/image/${local.update_schematic_id}/${local.update_version}/${var.talos_image.platform}-${var.talos_image.arch}.raw.gz"
update_image_id = "${local.update_schematic_id}_${local.update_version}" update_image_id = "${local.update_schematic_id}_${local.update_version}"
} }
data "http" "schematic_id" { data "http" "schematic_id" {
url = "${var.talos_image.factory_url}/schematics" url = "${var.image.factory_url}/schematics"
method = "POST" method = "POST"
request_body = local.schematic request_body = local.schematic
} }
data "http" "updated_schematic_id" { data "http" "updated_schematic_id" {
url = "${var.talos_image.factory_url}/schematics" url = "${var.image.factory_url}/schematics"
method = "POST" method = "POST"
request_body = local.update_schematic request_body = local.update_schematic
} }
resource "proxmox_virtual_environment_download_file" "talos_image" { resource "proxmox_virtual_environment_download_file" "this" {
for_each = toset(distinct([for k, v in var.cluster_config.nodes : "${v.host_node}_${v.update == true ? local.update_image_id : local.image_id}"])) for_each = toset(distinct([for k, v in var.nodes : "${v.host_node}_${v.update == true ? local.update_image_id : local.image_id}"]))
node_name = split("_", each.key)[0] node_name = split("_", each.key)[0]
content_type = "iso" content_type = "iso"
datastore_id = var.talos_image.proxmox_datastore datastore_id = var.image.proxmox_datastore
file_name = "talos-${split("_",each.key)[1]}-${split("_", each.key)[2]}-${var.talos_image.platform}-${var.talos_image.arch}.img" file_name = "talos-${split("_",each.key)[1]}-${split("_", each.key)[2]}-${var.image.platform}-${var.image.arch}.img"
url = "${var.talos_image.factory_url}/image/${split("_", each.key)[1]}/${split("_", each.key)[2]}/${var.talos_image.platform}-${var.talos_image.arch}.raw.gz" url = "${var.image.factory_url}/image/${split("_", each.key)[1]}/${split("_", each.key)[2]}/${var.image.platform}-${var.image.arch}.raw.gz"
decompression_algorithm = "gz" decompression_algorithm = "gz"
overwrite = false overwrite = false
} }

View File

@@ -1,13 +1,13 @@
output "talos_machine_config" { output "machine_config" {
value = data.talos_machine_configuration.machine_configuration value = data.talos_machine_configuration.this
} }
output "talos_client_configuration" { output "client_configuration" {
value = data.talos_client_configuration.talos_config value = data.talos_client_configuration.this
sensitive = true sensitive = true
} }
output "talos_kube_config" { output "kube_config" {
value = data.talos_cluster_kubeconfig.kubeconfig value = data.talos_cluster_kubeconfig.this
sensitive = true sensitive = true
} }

View File

@@ -1,77 +0,0 @@
resource "talos_machine_secrets" "machine_secrets" {
talos_version = var.cluster_config.talos_version
}
data "talos_client_configuration" "talos_config" {
cluster_name = var.cluster_config.cluster_name
client_configuration = talos_machine_secrets.machine_secrets.client_configuration
endpoints = [for k, v in var.cluster_config.nodes : v.ip if v.machine_type == "controlplane"]
}
data "talos_machine_configuration" "machine_configuration" {
for_each = var.cluster_config.nodes
cluster_name = var.cluster_config.cluster_name
cluster_endpoint = var.cluster_config.endpoint
machine_type = each.value.machine_type
machine_secrets = talos_machine_secrets.machine_secrets.machine_secrets
talos_version = var.cluster_config.talos_version
config_patches = each.value.machine_type == "controlplane" ? [
templatefile("${path.module}/machine-config/control-plane.yaml.tftpl", {
hostname = each.key
cluster_name = var.cluster_config.proxmox_cluster
node_name = each.value.host_node
cilium_values = var.cilium.values
cilium_install = var.cilium.install
})
] : [
templatefile("${path.module}/machine-config/worker.yaml.tftpl", {
hostname = each.key
cluster_name = var.cluster_config.proxmox_cluster
node_name = each.value.host_node
})
]
}
resource "talos_machine_configuration_apply" "talos_config_apply" {
depends_on = [proxmox_virtual_environment_vm.talos_vm]
for_each = var.cluster_config.nodes
node = each.value.ip
client_configuration = talos_machine_secrets.machine_secrets.client_configuration
machine_configuration_input = data.talos_machine_configuration.machine_configuration[each.key].machine_configuration
lifecycle {
# re-run config apply if vm changes
replace_triggered_by = [proxmox_virtual_environment_vm.talos_vm[each.key]]
}
}
resource "talos_machine_bootstrap" "talos_bootstrap" {
depends_on = [talos_machine_configuration_apply.talos_config_apply]
client_configuration = talos_machine_secrets.machine_secrets.client_configuration
node = [for k, v in var.cluster_config.nodes : v.ip if v.machine_type == "controlplane"][0]
}
data "talos_cluster_health" "health" {
depends_on = [
talos_machine_configuration_apply.talos_config_apply,
talos_machine_bootstrap.talos_bootstrap
]
client_configuration = data.talos_client_configuration.talos_config.client_configuration
control_plane_nodes = [for k, v in var.cluster_config.nodes : v.ip if v.machine_type == "controlplane"]
worker_nodes = [for k, v in var.cluster_config.nodes : v.ip if v.machine_type == "worker"]
endpoints = data.talos_client_configuration.talos_config.endpoints
timeouts = {
read = "10m"
}
}
data "talos_cluster_kubeconfig" "kubeconfig" {
depends_on = [
talos_machine_bootstrap.talos_bootstrap,
data.talos_cluster_health.health
]
client_configuration = talos_machine_secrets.machine_secrets.client_configuration
node = [for k, v in var.cluster_config.nodes : v.ip if v.machine_type == "controlplane"][0]
timeouts = {
read = "1m"
}
}

View File

@@ -1,4 +1,5 @@
variable "talos_image" { variable "image" {
description = "Talos image configuration"
type = object({ type = object({
factory_url = optional(string, "https://factory.talos.dev") factory_url = optional(string, "https://factory.talos.dev")
schematic = string schematic = string
@@ -11,32 +12,37 @@ variable "talos_image" {
}) })
} }
variable "cluster_config" { variable "cluster" {
description = "Talos node configuration" description = "Cluster configuration"
type = object({ type = object({
name = string
cluster_name = string
proxmox_cluster = string
endpoint = string endpoint = string
gateway = string
talos_version = string talos_version = string
proxmox_cluster = string
nodes = map(object({
host_node = string
machine_type = string
ip = string
mac_address = string
vm_id = number
cpu = number
ram_dedicated = number
update = optional(bool, false)
igpu = optional(bool, false)
}))
}) })
} }
variable "nodes" {
description = "Configuration for cluster nodes"
type = map(object({
host_node = string
machine_type = string
datastore_id = optional(string, "local-zfs")
ip = string
mac_address = string
vm_id = number
cpu = number
ram_dedicated = number
update = optional(bool, false)
igpu = optional(bool, false)
}))
}
variable "cilium" { variable "cilium" {
description = "Cilium configuration"
type = object({ type = object({
values = string values = string
install = string install = string
}) })
} }

View File

@@ -1,5 +1,5 @@
resource "proxmox_virtual_environment_vm" "talos_vm" { resource "proxmox_virtual_environment_vm" "this" {
for_each = var.cluster_config.nodes for_each = var.nodes
node_name = each.value.host_node node_name = each.value.host_node
@@ -32,7 +32,7 @@ resource "proxmox_virtual_environment_vm" "talos_vm" {
} }
disk { disk {
datastore_id = "local-zfs" datastore_id = each.value.datastore_id
interface = "scsi0" interface = "scsi0"
iothread = true iothread = true
cache = "writethrough" cache = "writethrough"
@@ -40,7 +40,7 @@ resource "proxmox_virtual_environment_vm" "talos_vm" {
ssd = true ssd = true
file_format = "raw" file_format = "raw"
size = 20 size = 20
file_id = proxmox_virtual_environment_download_file.talos_image["${each.value.host_node}_${each.value.update == true ? local.update_image_id : local.image_id}"].id file_id = proxmox_virtual_environment_download_file.this["${each.value.host_node}_${each.value.update == true ? local.update_image_id : local.image_id}"].id
} }
boot_order = ["scsi0"] boot_order = ["scsi0"]
@@ -50,14 +50,11 @@ resource "proxmox_virtual_environment_vm" "talos_vm" {
} }
initialization { initialization {
datastore_id = "local-zfs" datastore_id = each.value.datastore_id
ip_config { ip_config {
ipv4 { ipv4 {
address = "${each.value.ip}/24" address = "${each.value.ip}/24"
gateway = "192.168.1.1" gateway = var.cluster.gateway
}
ipv6 {
address = "dhcp"
} }
} }
} }