refactor: node selection
This commit is contained in:
@@ -1,46 +1,95 @@
|
|||||||
module "pve_vm" {
|
data "proxmox_virtual_environment_nodes" "pve_nodes" {}
|
||||||
source = "../../modules/pve_vm"
|
|
||||||
for_each = local.vm_list
|
|
||||||
node_name = each.value.node_name
|
|
||||||
vm_name = each.key
|
|
||||||
vm_cpu = each.value.vm_cpu
|
|
||||||
vm_ram = each.value.vm_ram
|
|
||||||
vm_vlan = each.value.vm_vlan
|
|
||||||
vm_tags = ["${var.vm_env}"]
|
|
||||||
}
|
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
node_stats = [
|
# ---------------------------------------------------------------------------
|
||||||
for i, name in data.proxmox_virtual_environment_nodes.pve_nodes.names : {
|
# Proxmox nodes online + available memory
|
||||||
name = name
|
# ---------------------------------------------------------------------------
|
||||||
free_mib = floor(data.proxmox_virtual_environment_nodes.pve_nodes.memory_available[i] / 1024 / 1024)
|
|
||||||
}
|
node_stats = {
|
||||||
|
for i, name in data.proxmox_virtual_environment_nodes.pve_nodes.names :
|
||||||
|
name => floor(
|
||||||
|
data.proxmox_virtual_environment_nodes.pve_nodes.memory_available[i]
|
||||||
|
/ 1024
|
||||||
|
/ 1024
|
||||||
|
)
|
||||||
if data.proxmox_virtual_environment_nodes.pve_nodes.online[i]
|
if data.proxmox_virtual_environment_nodes.pve_nodes.online[i]
|
||||||
]
|
}
|
||||||
|
|
||||||
max_free_mib = length(local.node_stats) > 0 ? max([for node in local.node_stats : node.free_mib]...) : 0
|
# ---------------------------------------------------------------------------
|
||||||
|
# Nodes ordered by available memory, most available first
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
max_free_mib = length(local.node_stats) > 0
|
||||||
|
? max(values(local.node_stats)...)
|
||||||
|
: 0
|
||||||
|
|
||||||
# Online nodes ordered by available memory, most available first (name as tie-break)
|
|
||||||
node_order = [
|
node_order = [
|
||||||
for key in sort([
|
for key in sort([
|
||||||
for node in local.node_stats : "${format("%012d", local.max_free_mib - node.free_mib)}|${node.name}"
|
for node, free_mib in local.node_stats :
|
||||||
]) : split("|", key)[1]
|
"${format("%012d", local.max_free_mib - free_mib)}|${node}"
|
||||||
|
]) :
|
||||||
|
split("|", key)[1]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# VM layout
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
vm_layout = flatten([
|
vm_layout = flatten([
|
||||||
for role in ["master", "worker"] : [
|
for role in ["master", "worker"] : [
|
||||||
for i in range(role == "master" ? var.master_count : var.worker_count) : {
|
for i in range(
|
||||||
|
role == "master"
|
||||||
|
? var.master_count
|
||||||
|
: var.worker_count
|
||||||
|
) : {
|
||||||
vm_name = "kub-${var.vm_env}-${substr(role, 0, 1)}${format("%02d", i + 1)}"
|
vm_name = "kub-${var.vm_env}-${substr(role, 0, 1)}${format("%02d", i + 1)}"
|
||||||
seq_index = (role == "master" ? 0 : var.master_count) + i
|
|
||||||
|
seq_index = (
|
||||||
|
role == "master"
|
||||||
|
? 0
|
||||||
|
: var.master_count
|
||||||
|
) + i
|
||||||
|
|
||||||
vm_role = role
|
vm_role = role
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Nodes with enough memory for each VM type
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
master_nodes = [
|
||||||
|
for node in local.node_order :
|
||||||
|
node
|
||||||
|
if local.node_stats[node] >= var.vm_attr.master.ram
|
||||||
|
]
|
||||||
|
|
||||||
|
worker_nodes = [
|
||||||
|
for node in local.node_order :
|
||||||
|
node
|
||||||
|
if local.node_stats[node] >= var.vm_attr.worker.ram
|
||||||
|
]
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# VM list
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
vm_list = {
|
vm_list = {
|
||||||
for vm in local.vm_layout :
|
for vm in local.vm_layout :
|
||||||
vm.vm_name => {
|
vm.vm_name => {
|
||||||
node_name = length(local.node_order) > 0 ? local.node_order[vm.seq_index % length(local.node_order)] : ""
|
node_name = (
|
||||||
|
vm.vm_role == "master"
|
||||||
|
? local.master_nodes
|
||||||
|
: local.worker_nodes
|
||||||
|
)[
|
||||||
|
vm.seq_index % length(
|
||||||
|
vm.vm_role == "master"
|
||||||
|
? local.master_nodes
|
||||||
|
: local.worker_nodes
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
vm_cpu = var.vm_attr[vm.vm_role].cpu
|
vm_cpu = var.vm_attr[vm.vm_role].cpu
|
||||||
vm_ram = var.vm_attr[vm.vm_role].ram
|
vm_ram = var.vm_attr[vm.vm_role].ram
|
||||||
vm_vlan = var.vm_attr[vm.vm_role].vlan
|
vm_vlan = var.vm_attr[vm.vm_role].vlan
|
||||||
@@ -48,25 +97,74 @@ locals {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
roles = toset([for vm in local.vm_list : vm.vm_role])
|
roles = toset([
|
||||||
|
for vm in local.vm_list :
|
||||||
|
vm.vm_role
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
data "proxmox_virtual_environment_nodes" "pve_nodes" {}
|
module "pve_vm" {
|
||||||
|
source = "../../modules/pve_vm"
|
||||||
|
for_each = local.vm_list
|
||||||
|
|
||||||
|
node_name = each.value.node_name
|
||||||
|
vm_name = each.key
|
||||||
|
vm_cpu = each.value.vm_cpu
|
||||||
|
vm_ram = each.value.vm_ram
|
||||||
|
vm_vlan = each.value.vm_vlan
|
||||||
|
vm_tags = [var.vm_env]
|
||||||
|
}
|
||||||
|
|
||||||
output "vm_ip" {
|
output "vm_ip" {
|
||||||
value = { for k, v in module.pve_vm : k => v.vm_ip }
|
value = {
|
||||||
|
for k, v in module.pve_vm :
|
||||||
|
k => v.vm_ip
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "ansible_group" "vm_groups" {
|
resource "ansible_group" "vm_groups" {
|
||||||
for_each = local.roles
|
for_each = local.roles
|
||||||
|
|
||||||
name = each.key
|
name = each.key
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "ansible_host" "vm_hosts" {
|
resource "ansible_host" "vm_hosts" {
|
||||||
for_each = module.pve_vm
|
for_each = module.pve_vm
|
||||||
|
|
||||||
name = each.key
|
name = each.key
|
||||||
|
|
||||||
variables = {
|
variables = {
|
||||||
ansible_host = each.value.vm_ip
|
ansible_host = each.value.vm_ip
|
||||||
}
|
}
|
||||||
groups = [local.vm_list[each.key].vm_role]
|
|
||||||
|
groups = [
|
||||||
|
local.vm_list[each.key].vm_role
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "terraform_data" "validate_vm_placement" {
|
||||||
|
input = {
|
||||||
|
master_nodes = length(local.master_nodes)
|
||||||
|
worker_nodes = length(local.worker_nodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
precondition {
|
||||||
|
condition = (
|
||||||
|
var.master_count == 0 ||
|
||||||
|
length(local.master_nodes) > 0
|
||||||
|
)
|
||||||
|
|
||||||
|
error_message = "No online Proxmox node has enough RAM for a master VM."
|
||||||
|
}
|
||||||
|
|
||||||
|
precondition {
|
||||||
|
condition = (
|
||||||
|
var.worker_count == 0 ||
|
||||||
|
length(local.worker_nodes) > 0
|
||||||
|
)
|
||||||
|
|
||||||
|
error_message = "No online Proxmox node has enough RAM for a worker VM."
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user