Files
hcornet ee0a1766f4
Terraform - plan / plan (push) Failing after 6s
first
2026-09-16 10:16:01 +02:00

80 lines
3.0 KiB
Terraform

locals {
fqdn = "${var.vm_hostname}.${var.dns_domain}"
# Les clés sont lues dans les fichiers du répertoire key/. Un fichier
# référencé mais absent fait échouer le plan, ce qui est le comportement
# voulu : mieux vaut un plan rouge qu'une VM inaccessible.
# Un compte sans aucun fichier de clé n'est pas créé.
comptes = [
for compte in var.local_accounts : {
name = compte.name
gecos = compte.gecos
ssh_keys = [for fichier in compte.ssh_key_files : trimspace(file("${path.module}/${fichier}"))]
}
if length(compte.ssh_key_files) > 0
]
cles_root = [for fichier in var.root_ssh_key_files : trimspace(file("${path.module}/${fichier}"))]
toutes_les_cles = concat(local.cles_root, flatten([for compte in local.comptes : compte.ssh_keys]))
# root d'abord, puis les comptes réellement créés : c'est la liste exhaustive
# des comptes autorisés à ouvrir une session SSH.
allow_users = join(" ", concat(["root"], [for compte in local.comptes : compte.name]))
}
# Mot de passe root : sert à « su - » et à la console Proxmox, jamais en SSH.
# Il est généré une fois puis conservé dans l'état Terraform, à récupérer par
# le workflow de déploiement pour être déposé dans Vaultwarden.
resource "random_password" "root" {
length = var.root_password_length
special = true
min_upper = 2
min_lower = 2
min_numeric = 2
min_special = 2
override_special = "!@#%^&*()-_=+[]{}:,.?"
}
# Le fichier est déposé dans le contenu "snippets" du stockage, via SSH.
# Attention : cloud-init ne rejoue la configuration qu'au premier démarrage.
# Modifier ce snippet après coup n'a donc aucun effet sur une VM déjà installée.
resource "proxmox_virtual_environment_file" "user_data" {
content_type = "snippets"
datastore_id = var.snippet_datastore_id
node_name = var.pve_node
source_raw {
file_name = "${var.vm_hostname}-user-data.yaml"
data = templatefile("${path.module}/templates/user-data.yaml.tftpl", {
hostname = var.vm_hostname
fqdn = local.fqdn
timezone = var.timezone
locale = var.locale
comptes = local.comptes
cles_root = local.cles_root
allow_users = local.allow_users
admin_cidrs = var.ssh_allowed_cidrs
root_password_hash = random_password.root.bcrypt_hash
})
}
lifecycle {
# Garde-fou : une valeur qui n'est pas une clé publique produirait une VM
# sur laquelle personne ne pourrait se connecter, et cloud-init ne rejoue rien.
precondition {
condition = alltrue([
for cle in local.toutes_les_cles :
can(regex("^(ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp[0-9]+|sk-ssh-ed25519) AAAA", cle))
])
error_message = "Un des fichiers de key/ ne contient pas une clé publique valide."
}
precondition {
condition = length(local.comptes) > 0
error_message = "Aucun compte n'a de clé : la machine serait inaccessible."
}
}
}