Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018BAUeCFpDkRD6tU5wGsc1C
117 lines
3.5 KiB
HCL
117 lines
3.5 KiB
HCL
# =============================================================================
|
|
# Serveurs
|
|
# =============================================================================
|
|
# Topologie retenue (2 VMs, cf. docs/mise-en-prod/00 et Excel previsions couts) :
|
|
#
|
|
# app-01 CPX41 8 vCPU / 16 Go k3s server + tous les pods (stateless)
|
|
# db-01 CPX31 4 vCPU / 8 Go PostgreSQL 15 + Redis 7 (stateful, Docker)
|
|
#
|
|
# Pourquoi la base HORS de Kubernetes : PostgreSQL en StatefulSet apporte de la
|
|
# complexite (PV, ordre de demarrage, upgrades) sans aucun gain a cette echelle.
|
|
# Le hors-cluster rend les sauvegardes, la PITR et les restaurations triviales,
|
|
# et permet de reconstruire integralement le noeud app sans toucher aux donnees.
|
|
|
|
resource "hcloud_server" "app" {
|
|
name = "${var.project_name}-app-01"
|
|
server_type = var.app_server_type
|
|
image = var.image
|
|
location = var.location
|
|
ssh_keys = [hcloud_ssh_key.admin.id]
|
|
# Deux firewalls : le permanent, et celui que la CI ouvre puis referme.
|
|
firewall_ids = [hcloud_firewall.app.id, hcloud_firewall.cicd.id]
|
|
placement_group_id = hcloud_placement_group.spread.id
|
|
backups = var.enable_hetzner_backups
|
|
|
|
public_net {
|
|
ipv4_enabled = true
|
|
ipv6_enabled = true
|
|
}
|
|
|
|
network {
|
|
network_id = hcloud_network.main.id
|
|
ip = var.app_private_ip
|
|
}
|
|
|
|
user_data = templatefile("${path.module}/cloud-init.yaml.tftpl", {
|
|
hostname = "${var.project_name}-app-01"
|
|
deploy_user = var.deploy_user
|
|
ssh_public_key = var.ssh_public_key
|
|
})
|
|
|
|
labels = {
|
|
project = var.project_name
|
|
role = "app"
|
|
managed = "terraform"
|
|
}
|
|
|
|
depends_on = [hcloud_network_subnet.main]
|
|
|
|
lifecycle {
|
|
# Un changement d'image ou de user_data recreerait le serveur : on veut une
|
|
# decision explicite, pas une destruction silencieuse de la prod.
|
|
ignore_changes = [image, user_data]
|
|
}
|
|
}
|
|
|
|
resource "hcloud_server" "db" {
|
|
name = "${var.project_name}-db-01"
|
|
server_type = var.db_server_type
|
|
image = var.image
|
|
location = var.location
|
|
ssh_keys = [hcloud_ssh_key.admin.id]
|
|
firewall_ids = [hcloud_firewall.db.id]
|
|
placement_group_id = hcloud_placement_group.spread.id
|
|
backups = var.enable_hetzner_backups
|
|
|
|
public_net {
|
|
ipv4_enabled = true
|
|
ipv6_enabled = true
|
|
}
|
|
|
|
network {
|
|
network_id = hcloud_network.main.id
|
|
ip = var.db_private_ip
|
|
}
|
|
|
|
user_data = templatefile("${path.module}/cloud-init.yaml.tftpl", {
|
|
hostname = "${var.project_name}-db-01"
|
|
deploy_user = var.deploy_user
|
|
ssh_public_key = var.ssh_public_key
|
|
})
|
|
|
|
labels = {
|
|
project = var.project_name
|
|
role = "data"
|
|
managed = "terraform"
|
|
}
|
|
|
|
depends_on = [hcloud_network_subnet.main]
|
|
|
|
lifecycle {
|
|
ignore_changes = [image, user_data]
|
|
}
|
|
}
|
|
|
|
# --- Volume de donnees PostgreSQL -------------------------------------------
|
|
# Volume dedie plutot que le disque systeme : agrandissable a chaud, snapshotable
|
|
# independamment, et survit a une reinstallation complete du serveur.
|
|
|
|
resource "hcloud_volume" "pgdata" {
|
|
name = "${var.project_name}-pgdata"
|
|
size = var.db_volume_size
|
|
server_id = hcloud_server.db.id
|
|
automount = false
|
|
format = "ext4"
|
|
|
|
labels = {
|
|
project = var.project_name
|
|
role = "pgdata"
|
|
managed = "terraform"
|
|
}
|
|
|
|
lifecycle {
|
|
# Garde-fou : un `terraform destroy` ne doit jamais emporter les donnees.
|
|
prevent_destroy = true
|
|
}
|
|
}
|