Migration provider bpg, templates cloud-init propres, cluster k3s HA (control-plane)

This commit is contained in:
2026-08-23 14:28:44 +02:00
parent 115541aac0
commit c7a9f6fa06
7 changed files with 349 additions and 26 deletions
Binary file not shown.
+24
View File
@@ -0,0 +1,24 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/bpg/proxmox" {
version = "0.111.1"
constraints = "0.111.1"
hashes = [
"h1:iTQv4FVFhMVl2juw6lgrVTpGFrdmdNPj+NFY2Dms0SE=",
"zh:18fb7c31a08dde6bffa1a4d4a211e604d6d17eec7092fd59331b3db3c6f3742c",
"zh:1cd60761538289d4dd2a1086b3ae62a7b0bdd4b1a2f824e9a44e243413168dba",
"zh:2eb76f6fc8299b6820ff678c8252332cc3366e226b5ae2e61748fd2449c1ed92",
"zh:45e6f7ebd0bf48911d37060359a4f359b5743b3092e985295733990e406d0416",
"zh:4aa8ba912eae37975d2e983394d173e595ca34fc76b5bf220b37d0e99d76e98c",
"zh:58e0789923103a77d502a0a9fc3eb920625e8eb935ec2d4ac0d006aebd1d186c",
"zh:6df8aa85fb8865915537e946c19b02538ad188018a629759c213c6f03730f642",
"zh:6ed47bc00d0913a1d0880618fa1376115e9edab6b4a658c081061a7f0e4ca360",
"zh:c5b10ff4f33df7e4c29e8f1127d49845b561b37b57517e844fb0954d7923d65e",
"zh:d016510e14b738499f0db9d9b3aafe82fc6877fb4ab4e9f831fb68a8d70a1385",
"zh:d941f394069bbf24351b363da1c64383f487067aaee0a84f9b96476d4912e212",
"zh:ddf271dbc2632ae8ffa8de3972f243ee47d260cb2ac90aa784f2746d98e21a0f",
"zh:ed0caa3501c42f611b7e9622c9b1df69fd85dc25a3cd88d3076381829688cd62",
"zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597",
]
}
+133
View File
@@ -0,0 +1,133 @@
# =============================================================================
# VMs Control-Plane k3s (HA, 3 nœuds, etcd embarqué)
# =============================================================================
# Une VM control-plane par hôte physique (PVE00, PVE01, PVE02), sur le VLAN 580
# (Infrastructure). PVE03 n'héberge pas de control-plane (réservé workers).
#
# Le template Debian 13 cloud-init (VMID 9000) est stocké sur `VMs_NFS`,
# storage partagé accessible depuis tous les nœuds du cluster — le clonage
# cross-node fonctionne donc nativement (testé et validé), sans duplication
# ni migration manuelle du template.
#
# Le disque de CHAQUE VM clonée est en revanche relocalisé vers le stockage
# ZFS local du nœud cible (`VM_POOL_RAID10` sur PVE00, `local-lvm` ailleurs)
# une fois le clone créé : etcd est sensible à la latence disque, et NFS
# n'est pas adapté à ce type de charge (cf. incident Postgres/NFS du même lab).
# =============================================================================
variable "k3s_cp_sshkeys_file" {
description = "Chemin du fichier contenant les clés SSH autorisées (cluster + poste de travail). Doit exister sur la machine qui exécute `terraform apply` (ex: Luffy), pas sur PVE00."
type = string
default = "./sshkeys.pub"
}
variable "k3s_cp_gateway" {
description = "Passerelle du VLAN 580 (Infrastructure)"
type = string
default = "192.168.80.254"
}
locals {
k3s_control_planes = {
"k3s-cp-00" = {
node_name = "pve00"
vm_id = 580
ip = "192.168.80.10"
datastore_id = "VM_POOL_RAID10" # ZFS local PVE00
}
"k3s-cp-01" = {
node_name = "pve01"
vm_id = 581
ip = "192.168.80.11"
datastore_id = "local-lvm" # LVM-thin local PVE01 (pas de ZFS sur ce nœud)
}
"k3s-cp-02" = {
node_name = "pve02"
vm_id = 582
ip = "192.168.80.12"
datastore_id = "local-lvm" # à adapter selon le storage réel disponible sur PVE02
}
}
}
resource "proxmox_virtual_environment_vm" "k3s_control_plane" {
for_each = local.k3s_control_planes
name = each.key
node_name = each.value.node_name
vm_id = each.value.vm_id
clone {
vm_id = 9000 # template debian13-cloudinit-template (stockage partagé VMs_NFS)
node_name = "pve00" # nœud où la config du template est enregistrée (le disque, lui, est sur VMs_NFS)
full = true
}
agent {
enabled = true
}
cpu {
cores = 2
sockets = 1
type = "x86-64-v2" # portable entre Coffee Lake / Skylake
}
memory {
dedicated = 4096
}
scsi_hardware = "virtio-scsi-single"
disk {
datastore_id = each.value.datastore_id
interface = "scsi0"
size = 20
iothread = true
}
network_device {
bridge = "vmbr0"
model = "virtio"
vlan_id = 580
}
initialization {
datastore_id = each.value.datastore_id
ip_config {
ipv4 {
address = "${each.value.ip}/24"
gateway = var.k3s_cp_gateway
}
}
user_account {
username = "root"
keys = [for line in split("\n", replace(trimspace(file(var.k3s_cp_sshkeys_file)), "\r", "")) : line if line != ""]
}
}
operating_system {
type = "l26"
}
stop_on_destroy = true
}
output "k3s_control_plane_ips" {
value = { for k, v in local.k3s_control_planes : k => v.ip }
}
# =============================================================================
# NOTE — Storage du template
# =============================================================================
# Le template 9000 (et 9001 pour Ubuntu) est stocké sur `VMs_NFS`, storage
# partagé (content-type "Disk image" activé, accessible sur tous les nœuds).
# Le clonage cross-node fonctionne donc directement, sans étape manuelle.
#
# Vérifier avant tout `terraform apply` que `each.value.datastore_id` pointe
# bien vers un storage réellement disponible sur le nœud cible (`pvesm status`
# sur chaque nœud) — en particulier pour PVE02, dont le storage local n'a pas
# encore été vérifié à la date de rédaction de ce fichier.
# =============================================================================
+11 -14
View File
@@ -1,24 +1,21 @@
terraform {
required_providers {
proxmox = {
source = "Telmate/proxmox"
version = "3.0.2-rc07"
source = "bpg/proxmox"
version = "0.111.1"
}
}
}
provider "proxmox" {
pm_api_url = "https://192.168.76.43:8006/api2/json"
pm_api_token_id = "terraform-prov@pve!mytoken"
pm_api_token_secret = "5af2e198-4a8e-49ef-9a1e-56a6718e3abd"
pm_tls_insecure = true
endpoint = var.proxmox_endpoint
api_token = var.proxmox_api_token # format complet : "user@realm!tokenid=secret-uuid"
insecure = true # certificat auto-signé
# Limiter le parallélisme force le provider à être plus séquentiel sur les droits
pm_parallel = 1
# Optionnel : désactive le scan complet du stockage au démarrage
pm_timeout = 600
# Ajoute ces deux lignes pour stabiliser la session API
pm_log_enable = true
pm_log_file = "terraform-plugin-proxmox.log"
# SSH optionnel, seulement nécessaire pour certaines opérations avancées
# (upload de fichiers/snippets, import de disques bruts, etc.)
# ssh {
# agent = true
# username = "root"
# }
}
+18 -13
View File
@@ -1,19 +1,24 @@
# Accès SSH
variable "admin_username" {
description = "Nom d'utilisateur pour se connecter à la VM"
# Variables pour le projet IT-Konoha
# Ces variables peuvent être utilisées dans les fichiers .tf pour rendre la configuration plus flexible et réutilisable.
variable "proxmox_endpoint" {
description = "URL du endpoint Proxmox (ex: https://192.168.76.43:8006/) — SANS /api2/json à la fin"
type = string
default = "admin.almeyric"
}
/* variable "ssh_public_key" {
description = "Clé publique SSH"
variable "proxmox_api_token" {
description = "Token API complet Proxmox : user@realm!tokenid=secret"
type = string
sensitive = true
} */
# Tag environnement
variable "environment_tag" {
description = "Indique l'environnement de déploiement (dev, test, prod)"
type = string
default = "test"
}
variable "node_name" {
description = "Nœud Proxmox cible"
type = string
default = "pve00"
}
variable "vm_user_sshkey" {
description = "Clé publique SSH injectée via cloud-init"
type = string
}
+102
View File
@@ -0,0 +1,102 @@
# =============================================================================
# VMs applicatives — patron générique (map + for_each)
# =============================================================================
# Remplace l'ancien srv_docker_530.tf. Même structure que k3s-control-plane.tf :
# une entrée dans `local.nodes` = une VM. Facile à dupliquer pour un futur
# groupe de VMs (copier ce fichier, changer le nom des locals/resource/output).
#
# Actuellement vide de VM "vivante" : .20 (Immich) a été retiré du state
# Terraform (modifiée à la main, cf. historique) et .21 a été détruite lors
# du nettoyage du pool ZFS. Ajouter une entrée dans `local.nodes` pour toute
# nouvelle VM applicative à déployer sur ce modèle.
# =============================================================================
variable "nodes_sshkeys_file" {
description = "Fichier de clés SSH autorisées (cluster + poste de travail)"
type = string
default = "./sshkeys.pub"
}
locals {
# Exemple de structure attendue pour une future VM :
# "srv-jellyfin" = {
# node_name = "pve03"
# vm_id = 533
# ip = "192.168.30.22"
# gateway = "192.168.30.254"
# vlan_id = 530
# datastore_id = "local-lvm"
# cores = 2
# memory = 2048
# disk_size = 20
# }
nodes = {}
}
resource "proxmox_virtual_environment_vm" "nodes" {
for_each = local.nodes
name = each.key
node_name = each.value.node_name
vm_id = each.value.vm_id
clone {
vm_id = 9000 # template debian13-cloudinit-template (stockage partagé VMs_NFS)
full = true
}
agent {
enabled = true
}
cpu {
cores = each.value.cores
sockets = 1
type = "x86-64-v2"
}
memory {
dedicated = each.value.memory
}
scsi_hardware = "virtio-scsi-single"
disk {
datastore_id = each.value.datastore_id
interface = "scsi0"
size = each.value.disk_size
iothread = true
}
network_device {
bridge = "vmbr0"
model = "virtio"
vlan_id = each.value.vlan_id
}
initialization {
datastore_id = each.value.datastore_id
ip_config {
ipv4 {
address = "${each.value.ip}/24"
gateway = each.value.gateway
}
}
user_account {
username = "root"
keys = [for line in split("\n", replace(trimspace(file(var.nodes_sshkeys_file)), "\r", "")) : line if line != ""]
}
}
operating_system {
type = "l26"
}
stop_on_destroy = true
}
output "nodes_ips" {
value = { for k, v in local.nodes : k => v.ip }
}
@@ -0,0 +1,62 @@
resource "proxmox_virtual_environment_vm" "nodes" {
count = 2
name = "srv-docker-${count.index + 1}"
node_name = var.node_name
vm_id = 530 + count.index
clone {
vm_id = 8999 # vmid de ton template debian13-cloudinit
full = true
}
agent {
enabled = true
}
cpu {
cores = 2
sockets = 1
type = "host"
}
memory {
dedicated = 4096
}
scsi_hardware = "virtio-scsi-single"
disk {
datastore_id = "VM_POOL_RAID10"
interface = "scsi0"
size = 20
iothread = true
}
network_device {
bridge = "vmbr1"
model = "virtio"
vlan_id = 530
}
initialization {
datastore_id = "VM_POOL_RAID10" # stockage du disque cloud-init (ide2 par défaut)
ip_config {
ipv4 {
address = "192.168.30.2${count.index}/24"
gateway = "192.168.30.254"
}
}
user_account {
username = "root"
keys = [var.vm_user_sshkey]
}
}
operating_system {
type = "l26" # Linux 2.6+ kernel (Debian, Ubuntu, etc.)
}
stop_on_destroy = true
}