2023-10-23 10:44:10 -04:00

529 lines
11 KiB
HCL

# See:
# https://github.com/sk4zuzu/vm-pool/blob/master/terraform/redhat/nodes/domain.tf
# SEE: https://github.com/SUSE/ha-sap-terraform-deployments/blob/master/libvirt/modules/hana_node/main.tf#L21
#variable "tenant_networks" {
# type = any
# default = {}
#}
# Variables
# =====================
variable "name" {
description = "Instance name"
type = string
}
variable "domain" {
description = "Instance domain"
type = string
default = "localdomain"
}
variable "number" {
description = "Number of instances"
type = number
default = 1
}
#
// variable "prefix" {
// description = "String to prefix each instances"
// type = string
// default = ""
// }
variable "name_fqdn" {
description = "Use fqdn to name instance ?"
type = bool
default = false
}
// variable "name_prefix" {
// description = "Define instance name with project prefix"
// type = bool
// default = true
// }
variable "instance_pool" {
description = "Volume pool for instance disks"
type = string
default = "default"
}
variable "disk_gb" {
description = "Size in gb of the root disk"
type = number
default = 2
}
#
variable "flavor" {
description = "Instance flavor"
type = string
default = "x-small"
}
variable "memory" {
description = "Instance memory"
type = string
default = "2048"
}
variable "vcpu" {
description = "Number of vcpu"
type = number
default = 2
}
variable "images" {
description = "Available OS images"
type = any
default = {}
}
variable "os" {
description = "Instance os"
type = string
default = "cirros_0.5"
}
variable "image_base_pool" {
description = "Default image pool"
type = string
default = "default"
}
variable "image_base_file" {
description = "Image base file in the image_pool"
type = string
default = "TEST__ MISSING"
}
variable "image_cloud_init" {
description = "Cloud init to use with this image"
type = string
default = "TEST__ CLOUDINIT CONFIG"
}
variable "cloudinit_userdata" {
description = "Cloud init userdata"
type = string
default = "TEST__ CLOUDINIT CONFIG222"
}
variable "cloudinit_file" {
description = "Cloud init userdata"
type = string
default = "/non_existant"
nullable = false
}
variable "cloudinit_vars" {
description = "Cloud init varaibles"
type = any
default = {}
nullable = false
}
variable "disks" {
description = "Ephemeral disks list"
type = list
default = []
}
variable "volumes" {
description = "Persistant volume list"
type = list
default = []
}
variable "networks" {
description = "Network list"
type = list
default = []
}
variable "wait_for_lease" {
description = "Wait for network ip assignment"
type = bool
default = null
}
variable "metadata" {
description = "Metadata do add in state"
type = any
default = {}
nullable = false
}
# Cloud init
# -----------
variable "user" {
description = "Default user login"
type = string
default = "cloud"
}
variable "authorized_key" {
description = "Default user authorized key"
type = string
default = ""
}
# Note: This should only be used for debugging purpose
variable "password_hash" {
description = "Default user password hash (ie: $1$SaltSalt$GhE887kYCerthShgxern00)"
type = string
default = ""
# sensitive = true
}
# Cloud settings
# =====================
// module "system_os" {
// source = "../../modules/virt_os"
// count = var.number
// os_name = "debian"
// os_version = "10"
// domain = var.domain
// hostname = "${var.name}${count.index}"
// user = var.user
// password_hash = var.password_hash
// authorized_key = var.authorized_key
// }
// module "system_flavor" {
// source = "../../modules/virt_flavor"
// count = var.number
// flavor = var.flavor
// }
# Volumes Configuration
# =====================
module "volume_cloudinit" {
source = "../virt_cloudinit"
count = var.number
name = "inst_${var.name}${count.index}_cloudinit.iso"
pool = var.instance_pool
// userdata = module.system_os[count.index].template
// userdata = var.cloudinit_userdata
userdata = templatefile(
var.cloudinit_file,
merge(
local.parsed_cloudinit_vars,
{
hostname = "${local.vm_name}${count.index}"
fqdn = "${local.vm_name}${count.index}.${var.domain}"
instance_index = count.index
}
)
)
}
module "volume_os" {
source = "../virt_volume"
count = var.number
format = "qcow2"
name = "inst_${var.name}${count.index}_os"
pool = var.instance_pool
size_gb = var.disk_gb
base_pool = var.image_base_pool
# TOFIX: Hardcoded refrence to debian
#base_file = "debian_latest.qcow2"
// base_file = "TEST__${var.os} --"
base_file = var.image_base_file
}
module "volumes_extra" {
source = "../virt_volumes"
count = var.number
volumes = var.disks
volumes_defaults = {
prefix = "inst_${var.name}${count.index}_"
pool = var.instance_pool
# TOFIX: Hardcoded variable
pool_dir = "/virt"
}
}
# Instance
# =====================
locals {
hostname = replace( var.name, "_", "-")
vm_name = "${local.hostname}"
domain = var.domain
vm_name_suffix = ( var.name_fqdn ?
".${var.domain}" :
"" )
vm_name_domain = ( var.domain != "" ?
".${var.domain}" :
"" )
metadata = merge(
{
domain = var.domain
// user = "FAILED" # var.user
// #password_hash = var.password_hash
// authorized_key = var.authorized_key
user = "cloud"
authorized_key = ""
authorized_keys = []
timezone = ""
instance_name = local.vm_name
instance_fqdn = "${local.vm_name}${local.vm_name_domain}"
},
var.metadata
)
cloudinit_vars = merge(
{
// hostname = ""
// domain = ""
// allow_passwords = false
// user = ""
// password_hash = ""
// authorized_key = ""
authorized_keys = []
packages = []
commands = []
},
var.cloudinit_vars
)
parsed_cloudinit_vars = merge(local.metadata, local.cloudinit_vars)
default_net_interface = {
network_name = null
mac = null
addresses = null
hostname = null
wait_for_lease = null
macvtap = null
vepa = null
}
networks = [for item in var.networks:
merge(local.default_net_interface, item)
]
// parsed_cloudinit = templatefile(var.cloudinit_file, local.cloudinit_vars)
// parsed_cloudinit = fileexists(var.cloudinit_file) ? templatefile(var.cloudinit_file, local.cloudinit_vars) : "NONE"
// parsed_cloudinit = try(templatefile(var.cloudinit_file, local.cloudinit_vars), null)
// parsed_cloudinit = templatefile(var.cloudinit_file, local.cloudinit_vars)
// parsed_cloudinit = templatefile(var.cloudinit_file, merge(local.cloudinit_vars, local.metadata))
// parsed_cloudinit = templatefile(var.cloudinit_file, local.parsed_cloudinit_vars)
}
resource "local_file" "config_deployment" {
count = var.number
// content = yamlencode(local.parsed_cloudinit)
// content = yamlencode(local.parsed_cloudinit_vars)
content = yamlencode(resource.libvirt_domain.instdef)
// try(resource.libvirt_domain.instdef, null)
filename = "out/INST-${var.name}-${count.index}.yml"
}
resource "libvirt_domain" "instdef" {
count = var.number
autostart = true
name = "${local.vm_name}${count.index}${local.vm_name_suffix}"
// vm_name = ( var.name_fqdn ?
// "${local.vmname}${count.index}.${var.domain}" :
// "${local.vmname}${count.index}" )
description = "${local.vm_name}${count.index}${local.vm_name_domain}"
memory = var.memory
vcpu = var.vcpu
// metadata = jsonencode(local.metadata)
metadata = jsonencode(merge(
local.metadata,
{
hostname = "${local.vm_name}${count.index}"
fqdn = "${local.vm_name}${count.index}.${var.domain}"
instance_index = count.index
}
)
)
# Root FS
# -------------------
cloudinit = module.volume_cloudinit[count.index].volume.id
disk {
volume_id = module.volume_os[count.index].volume.id
}
# Instance disks
dynamic "disk" {
for_each = module.volumes_extra[count.index].volumes
content {
volume_id = disk.value.volume.id
#volume_id = disk.value.info.id
#volume_id = coalesce(disk.value.volume.id)
#file = coalesce(disk.value.info.id)
}
}
# Networking
# -------------------
dynamic "network_interface" {
for_each = local.networks
content {
network_name = network_interface.value.name
mac = try(network_interface.value.mac, null)
addresses = try(network_interface.value.addresses, null)
#hostname = try(network_interface.value.hostname, var.name)
// wait for lease on first interface only by default
wait_for_lease = coalesce(network_interface.value.wait_for_lease, var.wait_for_lease, index(local.networks, network_interface.value) == 0 ? true: false )
macvtap = try(network_interface.value.macvtap, null)
vepa = try(network_interface.value.vepa, null)
}
}
# Other
# -------------------
console {
type = "pty"
target_port = "0"
target_type = "serial"
}
console {
type = "pty"
target_type = "virtio"
target_port = "1"
}
graphics {
type = "spice"
listen_type = "address"
autoport = true
}
cpu {
mode = "host-passthrough"
}
}
# Outputs
# =====================
output "instance" {
value = try(resource.libvirt_domain.instdef, null)
}
# output "volume_cloudinit" {
# value = module.volume_cloudinit
# }
// output "volume_os" {
// value = module.volume_os
// }
// output "volumes_extra" {
// value = module.volumes_extra
// }
// # Tag infos
// output "system_os" {
// value = module.system_os
// }
// output "system_flavor" {
// value = module.system_flavor
// }
// resource "ansible_host" "ansible_def" {
// count = var.number
// inventory_hostname = ( var.name_fqdn ?
// "${local.hostname}${count.index}.${var.domain}" :
// "${local.hostname}${count.index}" )
// #groups = [
// # "role_${local.hostname}",
// # var.prefix != "" ? "prj_${var.prefix}" : ""
// # ]
// vars = {
// ansible_user = var.user
// ansible_host = "${local.hostname}${count.index}.${var.domain}"
// ansible_connection = "ssh"
// instances_count = var.number
// instances_index = count.index
// instance_domain = var.domain
// instance_hostname = "${local.hostname}${count.index}"
// instance_name = "${local.hostname}"
// instance_provisionning_key = var.authorized_key
// instance_provisionning_user = var.user
// instance_flavor = var.flavor
// instance_metadata = jsonencode(merge(local.metadata, var.metadata))
// # TOFIX: lol
// instance_os_name = "debian"
// instance_os_version = "10"
// instance_vm = ( var.name_fqdn ?
// "${local.vmname}${count.index}.${var.domain}" :
// "${local.vmname}${count.index}" )
// }
// }