Compare commits
25 Commits
b652694b26
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaa329e70d | ||
|
|
eee527a9bc | ||
| d0e49254ab | |||
|
|
fc32f62aa2 | ||
|
|
28e0ee7369 | ||
|
|
df9934b48a | ||
|
|
09d3c84a87 | ||
|
|
b1b165c752 | ||
|
|
0e2593234a | ||
|
|
842c24acd8 | ||
|
|
adbc4ff64b | ||
|
|
fa33c842db | ||
|
|
06df079bfb | ||
| 9bce5603fc | |||
|
|
66106c5ac0 | ||
| 6c4e3c31b0 | |||
|
|
2ef6995c74 | ||
|
|
3ce22b493c | ||
| 452ebb1ac0 | |||
| a5d1e2b817 | |||
|
|
41dae6a086 | ||
| 43ba14df60 | |||
|
|
a9fdb3ac45 | ||
|
|
a66142632c | ||
|
|
f3f84168c3 |
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
70
cloud-init/user-data-alpine.yml.tftpl
Normal file
70
cloud-init/user-data-alpine.yml.tftpl
Normal 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} ]
|
||||||
50
cloud-init/user-data-systemd.yml.tftpl
Normal file
50
cloud-init/user-data-systemd.yml.tftpl
Normal 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" ]
|
||||||
@@ -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} ]
|
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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",
|
||||||
|
{
|
||||||
|
# User information
|
||||||
username = lookup(each.value, "username", var.default_vm_user)
|
username = lookup(each.value, "username", var.default_vm_user)
|
||||||
ssh_key = local.ssh_public_key
|
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 variables
|
||||||
|
vm_name = each.key
|
||||||
tailscale_auth_key = var.tailscale_auth_key
|
tailscale_auth_key = var.tailscale_auth_key
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
file_name = "${each.key}-cloud-init.yml"
|
file_name = "${each.key}-cloud-init.yml"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,23 +34,23 @@ admin_ssh_public_key_path = "~/.ssh/keys/id_rsa.pub"
|
|||||||
default_vm_user = "damien"
|
default_vm_user = "damien"
|
||||||
|
|
||||||
virtual_machines = {
|
virtual_machines = {
|
||||||
"ipfabric" = {
|
|
||||||
os = "ipfabric"
|
|
||||||
cores = 4
|
|
||||||
memory = 16384
|
|
||||||
disk_gb = 128
|
|
||||||
ip = "192.168.1.161"
|
|
||||||
gateway = "192.168.1.254"
|
|
||||||
tags = ["ipfabric"]
|
|
||||||
},
|
|
||||||
"komodo" = {
|
"komodo" = {
|
||||||
os = "alpine"
|
os = "alpine"
|
||||||
cores = 16
|
cores = 16
|
||||||
memory = 32768
|
memory = 32768
|
||||||
disk_gb = 32
|
disk_gb = 32
|
||||||
ip = "192.168.1.162"
|
ip = "192.168.1.161"
|
||||||
gateway = "192.168.1.254"
|
gateway = "192.168.1.254"
|
||||||
tags = ["docker"]
|
tags = ["docker"]
|
||||||
|
},
|
||||||
|
"ipfabric" = {
|
||||||
|
os = "ipfabric"
|
||||||
|
cores = 16
|
||||||
|
memory = 32768
|
||||||
|
disk_gb = 80
|
||||||
|
ip = "192.168.1.162"
|
||||||
|
gateway = "192.168.1.254"
|
||||||
|
tags = ["ipfabric"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
Reference in New Issue
Block a user