diff --git a/.gitignore b/.gitignore index 18f6eb0..06fb3df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,22 @@ -*.tfvars -!*.tfvars.example *.tfstate -*.tfstate.backup -*.out +*.tfstate.* +*.tfvars +*.tfvars.json +!*.tfvars.example .terraform/ -.terraform.lock.hcl +*.tfplan +*.out +crash.log +crash.*.log +override.tf +override.tf.json +*_override.tf +*_override.tf.json +.terraformrc +terraform.rc +.DS_Store +.idea/ +.vscode/ +*.swp +*.swo +*~ diff --git a/locals.tf b/locals.tf new file mode 100644 index 0000000..aae7eae --- /dev/null +++ b/locals.tf @@ -0,0 +1,19 @@ +locals { + # Alphabet pour la conversion base 26 des suffixes de noms de VMs. + letters = [ + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", + "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", + "u", "v", "w", "x", "y", "z" + ] + + # Dict des VMs a deployer, genere dynamiquement a partir de var.vm_count. + # cle = nom unique de la VM ex. "9999aaaa" + # value = parametres specifiques { vmid, ip } + vms = { + for i in range(var.vm_count) : + "9999aa${local.letters[floor(i / 26)]}${local.letters[i % 26]}" => { + vmid = 9010 + i + ip = cidrhost("10.1.90.0/24", 100 + i) + } + } +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..8eece42 --- /dev/null +++ b/main.tf @@ -0,0 +1,50 @@ +resource "proxmox_virtual_environment_vm" "lab" { + for_each = local.vms + + name = each.key + node_name = var.node_name + vm_id = each.value.vmid + + clone { + vm_id = var.template_id + full = true + } + + agent { + enabled = true + } + + cpu { + sockets = var.vm_cpu_sockets + cores = var.vm_cpu_cores + hotplugged = var.vm_cpu_hotplugged + } + + memory { + dedicated = var.vm_memory + } + + disk { + interface = "scsi0" + size = var.vm_disk_size + datastore_id = "local-lvm" + } + + network_device { + bridge = var.bridge + vlan_id = var.vlan_id + } + + initialization { + user_account { + username = var.ci_user + keys = [var.ssh_public_key] + } + ip_config { + ipv4 { + address = "${each.value.ip}/24" + gateway = var.gateway + } + } + } +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..3bfef95 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,17 @@ +output "vm_names" { + description = "Liste des noms de VMs creees" + value = [for k, v in proxmox_virtual_environment_vm.lab : v.name] +} + +output "vm_ips" { + description = "Mapping nom de VM -> IP" + value = { for name, vm in local.vms : name => vm.ip } +} + +output "ssh_commands" { + description = "Commandes SSH pretes a copier pour chaque VM" + value = [ + for name, vm in local.vms : + "ssh ${var.ci_user}@${vm.ip} # ${name}" + ] +} diff --git a/providers.tf b/providers.tf new file mode 100644 index 0000000..c5772d7 --- /dev/null +++ b/providers.tf @@ -0,0 +1,5 @@ +provider "proxmox" { + endpoint = var.proxmox_endpoint + api_token = var.proxmox_api_token + insecure = var.proxmox_insecure +} diff --git a/terraform.tfvars.example b/terraform.tfvars.example new file mode 100644 index 0000000..937d399 --- /dev/null +++ b/terraform.tfvars.example @@ -0,0 +1,16 @@ +# Copier en `terraform.tfvars` puis remplacer les placeholders par les vraies valeurs. +# Toutes les variables listees ici sont obligatoires (sans default cote variables.tf). +# +# Note : `vm_count` est aussi obligatoire mais volontairement absente ici pour +# etre promptee a chaque `tofu plan` / `tofu apply`. Decommenter la ligne en bas +# si tu veux la figer. + +proxmox_endpoint = "https://:8006" +proxmox_api_token = "root@pam!sio-routage=00000000-0000-0000-0000-000000000000" +proxmox_insecure = true + +node_name = "" + +ssh_public_key = "ssh-ed25519 AAAA... user@host" + +# vm_count = 3 diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..ba3d92d --- /dev/null +++ b/variables.tf @@ -0,0 +1,99 @@ +# =================== OBLIGATOIRES (sans default) =================== + +variable "proxmox_endpoint" { + description = "URL HTTPS Proxmox" + type = string +} + +variable "proxmox_api_token" { + description = "USER@REALM!TOKENID=SECRET" + type = string + sensitive = true +} + +variable "proxmox_insecure" { + description = "Skip TLS" + type = bool +} + +variable "node_name" { + description = "Nom du node PVE" + type = string +} + +variable "ssh_public_key" { + description = "Cle SSH publique cloudinit" + type = string +} + +variable "vm_count" { + description = "Nombre de VMs a deployer (1 a 90)" + type = number + + validation { + condition = var.vm_count >= 1 && var.vm_count <= 90 + error_message = "vm_count doit etre entre 1 et 90 (limite vm_id 9010-9099)." + } +} + +# =================== OPTIONNELLES (avec default) =================== + +variable "template_id" { + description = "ID Proxmox du template a cloner" + type = number + default = 100 +} + +variable "vm_cpu_sockets" { + description = "Nombre de sockets alloues a la VM" + type = number + default = 1 +} + +variable "vm_cpu_cores" { + description = "Nombre de vCPU alloues a la VM" + type = number + default = 12 +} + +variable "vm_cpu_hotplugged" { + description = "Nombre de vCPUs actifs au boot" + type = number + default = 2 +} + +variable "vm_memory" { + description = "RAM dediee a la VM en MiB" + type = number + default = 1024 +} + +variable "vm_disk_size" { + description = "Taille du disque en GiB" + type = number + default = 10 +} + +variable "bridge" { + description = "Bridge Proxmox" + type = string + default = "vmbr0" +} + +variable "vlan_id" { + description = "VLAN tag applique" + type = number + default = 90 +} + +variable "ci_user" { + description = "Compte unix cree par cloud-init" + type = string + default = "nidoradmin" +} + +variable "gateway" { + description = "Gateway IPv4 du subnet" + type = string + default = "10.1.90.1" +} diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..b234dd2 --- /dev/null +++ b/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.8" + + required_providers { + proxmox = { + source = "bpg/proxmox" + version = "~> 0.78" + } + } +}