80 lines
3.0 KiB
Terraform
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."
|
|
}
|
|
}
|
|
}
|