Le seul Terraform du dépôt installait un cluster k3s que rien ne consomme, et sa racine ne passait même pas `terraform init` : depuis Terraform 1.x, un provisioner `destroy` impose que tout le bloc `connection` ne lise que `self`, et celui du module k3s lisait `var.*`. Il est corrigé en batissant la connexion sur `triggers`, où ne figurent que l'adresse, le port, l'utilisateur et le chemin de la clé : jamais la clé ni un mot de passe. `environments/vm-eni` provisionne la machine qui porte la recette et la production : Docker et le plugin Compose, `scripts/provision-host.sh`, puis l'enregistrement du runner. Rien n'y construit d'image ni ne lance de conteneur, et un `apply` n'interrompt pas la stack qui tourne. Le déploiement continu ne bouge pas : `deploy.yml` reste le seul chemin de livraison. `environments/dev` devient `k3s-cible`, parce qu'il provisionnait un cluster et pas un environnement applicatif, et que `rec` et `prod` vivent sur la même machine. `environments/prod`, dossier vide, disparaît. `infra.yml` formate et valide chaque racine à chaque push : c'est l'absence d'un tel job qui a laissé ce Terraform cassé sans que rien ne le dise. La boucle parcourt `environments/*`, une racine ajoutée est couverte sans y toucher. ADR 0010 pour la frontière entre provisionnement et livraison, et la doc d'architecture alignée dessus.
63 lines
2.3 KiB
Terraform
63 lines
2.3 KiB
Terraform
locals {
|
|
sudo_prefix = var.ssh_user == "root" ? "" : "sudo "
|
|
install_env = "INSTALL_K3S_VERSION=${var.k3s_version} "
|
|
disable_flags = join(" ", [for c in var.k3s_disable_components : "--disable=${c}"])
|
|
kubeconfig_cmd = "${local.sudo_prefix}cat /etc/rancher/k3s/k3s.yaml"
|
|
}
|
|
|
|
# Piege : un provisioner `destroy` impose que tout le bloc `connection` ne lise que `self`, sinon
|
|
# `terraform init` refuse le module. D'ou la connexion batie sur `triggers`, ou ne figurent que
|
|
# l'adresse, le port, l'utilisateur et le chemin de la cle : jamais la cle ni un mot de passe.
|
|
resource "null_resource" "k3s_install" {
|
|
triggers = {
|
|
ssh_host = var.ssh_host
|
|
ssh_port = tostring(var.ssh_port)
|
|
ssh_user = var.ssh_user
|
|
ssh_key_path = var.ssh_private_key_path
|
|
sudo_prefix = local.sudo_prefix
|
|
k3s_version = var.k3s_version
|
|
disable_components = join(",", var.k3s_disable_components)
|
|
}
|
|
|
|
connection {
|
|
type = "ssh"
|
|
host = self.triggers.ssh_host
|
|
port = tonumber(self.triggers.ssh_port)
|
|
user = self.triggers.ssh_user
|
|
private_key = file(pathexpand(self.triggers.ssh_key_path))
|
|
}
|
|
|
|
provisioner "remote-exec" {
|
|
inline = [
|
|
"${local.sudo_prefix}sh -c 'curl -sfL https://get.k3s.io | ${local.install_env}sh -s - server ${local.disable_flags}'",
|
|
"until ${local.sudo_prefix}test -f /etc/rancher/k3s/k3s.yaml; do sleep 2; done",
|
|
]
|
|
}
|
|
|
|
# Le kubeconfig est lu via sudo (fetch_kubeconfig), pas besoin de --write-kubeconfig-mode :
|
|
# il reste 600/root par defaut, ce qui evite d'exposer les droits cluster-admin a tout utilisateur local.
|
|
provisioner "remote-exec" {
|
|
when = destroy
|
|
on_failure = continue
|
|
inline = [
|
|
"${self.triggers.sudo_prefix}sh -c 'test -x /usr/local/bin/k3s-uninstall.sh && /usr/local/bin/k3s-uninstall.sh || true'",
|
|
]
|
|
}
|
|
}
|
|
|
|
resource "null_resource" "fetch_kubeconfig" {
|
|
depends_on = [null_resource.k3s_install]
|
|
|
|
triggers = {
|
|
install_id = null_resource.k3s_install.id
|
|
}
|
|
|
|
provisioner "local-exec" {
|
|
interpreter = ["bash", "-c"]
|
|
command = <<-EOT
|
|
ssh -i "${var.ssh_private_key_path}" -p ${var.ssh_port} -o StrictHostKeyChecking=accept-new ${var.ssh_user}@${var.ssh_host} '${local.kubeconfig_cmd}' \
|
|
| sed 's/127.0.0.1/${var.ssh_host}/' > "${var.kubeconfig_output_path}"
|
|
EOT
|
|
}
|
|
}
|