Compare commits

..

27 Commits

Author SHA1 Message Date
Damien
eaa329e70d Update prod VM disk size to 80GB
All checks were successful
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Plan (push) Successful in 7s
Terraform Deploy / Apply (push) Successful in 4m0s
2026-06-21 13:01:37 +02:00
Damien
eee527a9bc Increase IP Fabric VM disk size to 64GB
Some checks failed
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Plan (push) Successful in 4s
Terraform Deploy / Apply (push) Failing after 2m24s
2026-06-21 12:58:30 +02:00
d0e49254ab Merge pull request 'Add IP Fabric VM to production' (#19) from feat/ipfabric_vm into dev
Some checks failed
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Plan (push) Successful in 6s
Terraform Deploy / Apply (push) Failing after 1m22s
Reviewed-on: #19
2026-06-21 10:55:01 +00:00
Damien
fc32f62aa2 Add IP Fabric VM to production
All checks were successful
Terraform PR / Validate (pull_request) Successful in 7s
Terraform PR / Plan (pull_request) Successful in 6s
2026-06-21 12:40:48 +02:00
Damien
28e0ee7369 Update prod VM configuration for Komodo
All checks were successful
Terraform Deploy / Validate (push) Successful in 6s
Terraform Deploy / Plan (push) Successful in 5s
Terraform Deploy / Apply (push) Successful in 2m27s
Replace IP Fabric VM with Komodo VM using Alpine OS and increased
resources
2026-06-14 15:39:47 +02:00
Damien
df9934b48a Remove komodo VM from prod configuration
Some checks failed
Terraform Deploy / Validate (push) Successful in 6s
Terraform Deploy / Plan (push) Successful in 5s
Terraform Deploy / Apply (push) Has been cancelled
2026-06-14 15:35:24 +02:00
Damien
09d3c84a87 Update user creation and Tailscale setup
Add Debian/Ubuntu/Rocky-specific user configuration
Improve Tailscale installation and bringup reliability
2026-06-10 10:49:49 +02:00
Damien
b1b165c752 Add komodo VM to production
All checks were successful
Terraform Deploy / Validate (push) Successful in 4s
Terraform Deploy / Plan (push) Successful in 4s
Terraform Deploy / Apply (push) Successful in 49s
2026-06-10 10:43:28 +02:00
Damien
0e2593234a Remove komodo virtual machine from prod
All checks were successful
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Plan (push) Successful in 4s
Terraform Deploy / Apply (push) Successful in 8s
2026-06-10 10:42:09 +02:00
Damien
842c24acd8 Unlock user account on Alpine
Use `passwd -u` workaround for reliable unlocking
2026-06-10 10:41:40 +02:00
Damien
adbc4ff64b Add komodo VM to production
All checks were successful
Terraform Deploy / Validate (push) Successful in 9s
Terraform Deploy / Plan (push) Successful in 9s
Terraform Deploy / Apply (push) Successful in 1m1s
2026-06-10 10:10:34 +02:00
Damien
fa33c842db Remove komodo virtual machine from prod configuration
All checks were successful
Terraform Deploy / Validate (push) Successful in 10s
Terraform Deploy / Plan (push) Successful in 11s
Terraform Deploy / Apply (push) Successful in 17s
2026-06-10 10:08:56 +02:00
Damien
06df079bfb Add lock_passwd false to Alpine user config 2026-06-10 10:08:06 +02:00
9bce5603fc Merge pull request 'Add production VMs for IP Fabric and Komodo' (#18) from vm/ipfabric_komodo into dev
All checks were successful
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Plan (push) Successful in 5s
Terraform Deploy / Apply (push) Successful in 1m35s
Reviewed-on: #18
2026-06-10 07:44:02 +00:00
Damien
66106c5ac0 Add production VMs for IP Fabric and Komodo
All checks were successful
Terraform PR / Validate (pull_request) Successful in 4s
Terraform PR / Plan (pull_request) Successful in 6s
2026-06-10 09:41:54 +02:00
6c4e3c31b0 Merge pull request 'Remove unused virtual machines from prod config' (#17) from vm/delete_all into dev
All checks were successful
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Plan (push) Successful in 6s
Terraform Deploy / Apply (push) Successful in 11s
Reviewed-on: #17
2026-06-10 07:40:24 +00:00
Damien
2ef6995c74 Remove unused virtual machines from prod config
All checks were successful
Terraform PR / Validate (pull_request) Successful in 5s
Terraform PR / Plan (pull_request) Successful in 8s
2026-06-10 09:32:32 +02:00
Damien
3ce22b493c Add shell specification to Terraform plan steps
Some checks failed
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Apply (push) Has been cancelled
Terraform Deploy / Plan (push) Has been cancelled
2026-06-10 09:29:24 +02:00
452ebb1ac0 Merge pull request 'Add DNS server configuration for Alpine Linux' (#16) from fix/alpine_dns into dev
Some checks failed
Terraform Deploy / Validate (push) Successful in 4s
Terraform Deploy / Apply (push) Has been cancelled
Terraform Deploy / Plan (push) Has been cancelled
Reviewed-on: #16
2026-06-10 07:15:26 +00:00
a5d1e2b817 Merge branch 'dev' into fix/alpine_dns
Some checks failed
Terraform PR / Validate (pull_request) Successful in 4s
Terraform PR / Plan (pull_request) Has been cancelled
2026-06-10 07:12:31 +00:00
Damien
41dae6a086 Add DNS server configuration for Alpine Linux
Some checks failed
Terraform PR / Validate (pull_request) Successful in 5s
Terraform PR / Plan (pull_request) Has been cancelled
2026-06-10 08:49:50 +02:00
43ba14df60 Merge pull request 'chore/fix_qemu_alpine' (#15) from chore/fix_qemu_alpine into dev
All checks were successful
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Plan (push) Successful in 4s
Terraform Deploy / Apply (push) Successful in 15m18s
Reviewed-on: #15
2026-06-10 06:22:44 +00:00
Damien
a9fdb3ac45 Add DNS configuration for VMs
All checks were successful
Terraform PR / Validate (pull_request) Successful in 5s
Terraform PR / Plan (pull_request) Successful in 5s
2026-06-10 08:18:37 +02:00
Damien
a66142632c Add Alpine and systemd cloud-init templates 2026-06-10 08:09:42 +02:00
Damien
f3f84168c3 Remove legacy cloud-init template
The user-data.yml.tftpl file was replaced with OS-specific templates to
support
different init systems. The new templates are
user-data-systemd.yml.tftpl and
user-data-alpine.yml.tftpl, selected based on the VM's OS type.
2026-06-10 08:09:36 +02:00
b652694b26 Merge pull request 'Add komodo VM to prod configuration' (#14) from vm/komodo into dev
All checks were successful
Terraform Deploy / Validate (push) Successful in 5s
Terraform Deploy / Plan (push) Successful in 5s
Terraform Deploy / Apply (push) Successful in 15m14s
Reviewed-on: #14
2026-06-09 17:35:44 +00:00
Damien
4a2704c6f3 Add komodo VM to prod configuration
All checks were successful
Terraform PR / Validate (pull_request) Successful in 9s
Terraform PR / Plan (pull_request) Successful in 5s
2026-06-09 17:22:20 +02:00
9 changed files with 174 additions and 50 deletions

View File

@@ -87,8 +87,8 @@ jobs:
- name: Terraform Plan - name: Terraform Plan
id: plan id: plan
shell: sh {0}
run: | run: |
set +e
terraform plan -input=false -no-color -detailed-exitcode -out=tfplan > plan_output.txt 2>&1 terraform plan -input=false -no-color -detailed-exitcode -out=tfplan > plan_output.txt 2>&1
EXITCODE=$? EXITCODE=$?
cat plan_output.txt cat plan_output.txt

View File

@@ -85,8 +85,8 @@ jobs:
- name: Terraform Plan - name: Terraform Plan
id: plan id: plan
shell: sh {0}
run: | run: |
set +e
terraform plan -input=false -no-color -detailed-exitcode -out=tfplan > plan_output.txt 2>&1 terraform plan -input=false -no-color -detailed-exitcode -out=tfplan > plan_output.txt 2>&1
EXITCODE=$? EXITCODE=$?
cat plan_output.txt cat plan_output.txt

View File

@@ -0,0 +1,70 @@
#cloud-config
# 1. Hostname configuration
hostname: ${hostname}
fqdn: ${hostname}
preserve_hostname: false
# 2. User creation
# On Alpine, the privilege escalation group is "wheel" (not "sudo").
# Keep the default shell (ash/busybox) to stay lightweight.
#
# IMPORTANT: lock_passwd MUST be false on Alpine.
# cloud-init's default (lock_passwd: true) sets shadow to "!", which Alpine's
# OpenSSH (compiled without PAM) interprets as "account locked" and refuses
# pubkey auth with "User ... not allowed because account is locked".
# Setting lock_passwd: false lets cloud-init use "*" instead: no password
# login possible, but pubkey works.
users:
- name: ${username}
sudo: ALL=(ALL) NOPASSWD:ALL
groups: wheel
shell: /bin/ash
lock_passwd: false
ssh_authorized_keys:
- ${ssh_key}
# 3. Base system files (DNS + apk repos, written before package_update)
# Alpine has no netplan/systemd-resolved, so we write resolv.conf ourselves.
write_files:
- path: /etc/resolv.conf
owner: root:root
permissions: '0644'
content: |
nameserver ${dns_server}
- path: /etc/apk/repositories
owner: root:root
permissions: '0644'
content: |
http://dl-cdn.alpinelinux.org/alpine/edge/main
http://dl-cdn.alpinelinux.org/alpine/edge/community
# 4. System update (apk)
package_update: true
package_upgrade: true
# 5. Package installation
# - qemu-guest-agent: main repo (required so Proxmox/Terraform can read the VM IP)
# - tailscale: community repo
packages:
- qemu-guest-agent
- curl
- sudo
- tailscale
# 6. Services & configuration (OpenRC, not systemd)
# Intentional order: qemu-guest-agent first to unblock Terraform as soon as possible.
runcmd:
# Enable and start qemu-guest-agent via OpenRC
- [ rc-update, add, qemu-guest-agent, default ]
- [ rc-service, qemu-guest-agent, start ]
# Unlock the user account: cloud-init's lock_passwd: false is unreliable on
# Alpine (passwd -u refuses on passwordless accounts), so we force the shadow
# entry to "*" ourselves. "*" means: no password login possible, but pubkey
# auth works (unlike "!" which sshd treats as locked).
- [ sh, -c, "sed -i 's/^${username}:!:/${username}:*:/' /etc/shadow" ]
# Enable and start Tailscale via OpenRC
- [ rc-update, add, tailscale, default ]
- [ rc-service, tailscale, start ]
# Register the node with the tailnet
- [ tailscale, up, --authkey=${tailscale_auth_key}, --hostname=${vm_name} ]

View File

@@ -0,0 +1,50 @@
#cloud-config
# 1. Hostname configuration
hostname: ${hostname}
fqdn: ${hostname}
preserve_hostname: false
# 2. User creation
#
# Unlike Alpine, sshd on Debian/Ubuntu/Rocky is built with PAM, which accepts
# pubkey auth even when the shadow entry is locked ("!"). So the Alpine
# /etc/shadow workaround is NOT needed here.
#
# Groups:
# - Debian/Ubuntu: sudo group grants admin rights
# - Rocky/RHEL: wheel group grants admin rights
# We include both so the same template works for all supported distros; cloud-
# init silently skips groups that don't exist on the target system.
# (The "admin" group is intentionally NOT included: it was deprecated on
# Ubuntu 12.04 and absent on RHEL-family distros.)
users:
- name: ${username}
sudo: ALL=(ALL) NOPASSWD:ALL
groups: [sudo, wheel]
shell: /bin/bash
lock_passwd: true
ssh_authorized_keys:
- ${ssh_key}
# 3. System update
package_update: true
package_upgrade: true
# 4. Package installation
packages:
- qemu-guest-agent
- curl
# 5. Services and Tailscale
# Order matters: qemu-guest-agent FIRST so Terraform can read the VM IP
# without waiting for the (potentially slow) Tailscale install.
runcmd:
# Enable and start qemu-guest-agent (systemd)
- [ systemctl, enable, qemu-guest-agent, --now ]
# Install Tailscale (official installer detects the distro)
- [ sh, -c, "curl -fsSL https://tailscale.com/install.sh | sh" ]
# Bring the node up on the tailnet. Retry a few times to absorb the small
# delay between `systemctl start tailscaled` and the daemon's socket being
# ready to accept commands.
- [ sh, -c, "for i in 1 2 3 4 5; do tailscale up --authkey=${tailscale_auth_key} --hostname=${vm_name} && break; sleep 2; done" ]

View File

@@ -1,32 +0,0 @@
#cloud-config
# 1. Configuration du nom d'hôte de la machine
hostname: ${hostname}
fqdn: ${hostname}
preserve_hostname: false
# 2. Création de l'utilisateur
users:
- name: ${username}
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo, admin
shell: /bin/bash
ssh_authorized_keys:
- ${ssh_key}
# 3. Mise à jour du système
package_update: true
package_upgrade: true
# 4. Installation des paquets
packages:
- qemu-guest-agent
- curl
# 5. Installation et configuration de Tailscale
runcmd:
# Enable and start qemu-guest-agent (systemd)
- [ systemctl, enable, qemu-guest-agent, --now ]
# Install and configure Tailscale
- [ sh, -c, "curl -fsSL https://tailscale.com/install.sh | sh" ]
- [ tailscale, up, --authkey=${tailscale_auth_key}, --hostname=${vm_name} ]

View File

@@ -78,6 +78,11 @@ resource "proxmox_virtual_environment_vm" "vms" {
# On utilise le bloc 'initialization' pour configurer Cloud-Init # On utilise le bloc 'initialization' pour configurer Cloud-Init
initialization { initialization {
# Configuration DNS (nécessaire au bootstrap : apt, curl, install Tailscale...)
dns {
servers = var.dns_servers
}
# Configuration IP # Configuration IP
ip_config { ip_config {
ipv4 { ipv4 {

View File

@@ -1,8 +1,18 @@
# Fichier: terraform/prod/02-cloud-init.tf # File: terraform/prod/02-cloud-init.tf
locals { locals {
# Utilise le contenu direct si fourni (CI), sinon lit depuis le fichier (local) # Use direct content if provided (CI), otherwise read from file (local).
ssh_public_key = var.admin_ssh_public_key != "" ? var.admin_ssh_public_key : file(var.admin_ssh_public_key_path) ssh_public_key = var.admin_ssh_public_key != "" ? var.admin_ssh_public_key : file(var.admin_ssh_public_key_path)
# OS -> cloud-init template family mapping.
# Selects the correct user-data based on init system / package manager.
os_template_family = {
ubuntu = "systemd"
debian = "systemd"
rocky = "systemd"
ipfabric = "systemd"
alpine = "alpine"
}
} }
resource "proxmox_virtual_environment_file" "cloud_config" { resource "proxmox_virtual_environment_file" "cloud_config" {
@@ -13,18 +23,24 @@ resource "proxmox_virtual_environment_file" "cloud_config" {
content_type = "snippets" content_type = "snippets"
source_raw { source_raw {
data = templatefile("${path.module}/../../cloud-init/user-data.yml.tftpl", { data = templatefile(
# Variables pour définir les informations de l'utilisateur "${path.module}/../../cloud-init/user-data-${local.os_template_family[each.value.os]}.yml.tftpl",
username = lookup(each.value, "username", var.default_vm_user) {
ssh_key = local.ssh_public_key # User information
username = lookup(each.value, "username", var.default_vm_user)
ssh_key = local.ssh_public_key
# Variables pour définir les informations de la VM # VM information
hostname = "${each.key}.${var.domain_suffix}" hostname = "${each.key}.${var.domain_suffix}"
# Nouvelles variables pour Tailscale # Network (used by templates that need to write /etc/resolv.conf themselves, e.g. Alpine)
vm_name = each.key # Le nom de la VM (ex: "web-01") dns_server = var.dns_servers[0]
tailscale_auth_key = var.tailscale_auth_key
}) # Tailscale variables
vm_name = each.key
tailscale_auth_key = var.tailscale_auth_key
}
)
file_name = "${each.key}-cloud-init.yml" file_name = "${each.key}-cloud-init.yml"
} }

View File

@@ -34,12 +34,21 @@ admin_ssh_public_key_path = "~/.ssh/keys/id_rsa.pub"
default_vm_user = "damien" default_vm_user = "damien"
virtual_machines = { virtual_machines = {
"komodo" = {
os = "alpine"
cores = 16
memory = 32768
disk_gb = 32
ip = "192.168.1.161"
gateway = "192.168.1.254"
tags = ["docker"]
},
"ipfabric" = { "ipfabric" = {
os = "ipfabric" os = "ipfabric"
cores = 4 cores = 16
memory = 16384 memory = 32768
disk_gb = 128 disk_gb = 80
ip = "192.168.1.161" ip = "192.168.1.162"
gateway = "192.168.1.254" gateway = "192.168.1.254"
tags = ["ipfabric"] tags = ["ipfabric"]
} }

View File

@@ -54,6 +54,12 @@ variable "default_vm_user" {
default = "root" default = "root"
} }
variable "dns_servers" {
description = "Liste des serveurs DNS pour les VMs (utilisés au bootstrap, avant la prise en charge éventuelle par Tailscale ou un autre service)."
type = list(string)
default = ["192.168.1.254"]
}
variable "virtual_machines" { variable "virtual_machines" {
description = "Configuration des machines virtuelles à déployer" description = "Configuration des machines virtuelles à déployer"
type = map(object({ type = map(object({