From 1cdc40f96e9ae3817b8d1219092ccd88d94ebb46 Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 13 Nov 2025 19:30:40 +0100 Subject: [PATCH 01/14] =?UTF-8?q?fix(ci):=20Downgrade=20upload-artifact=20?= =?UTF-8?q?v3=20pour=20compatibilit=C3=A9=20Forgejo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit upload-artifact@v4 n'est pas supporté sur Forgejo/GHES. Downgrade vers v3 pour assurer que uploads artifacts fonctionnent correctement. --- .forgejo/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 6fdf512..81492c6 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: - name: Upload Terraform Plan if: github.event_name == 'push' && github.ref == 'refs/heads/main' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3 with: name: tfplans path: terraform/pve*/tfplan-* From 9cb07375603e756a065a6b9b446e1839677d905f Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 13 Nov 2025 19:41:46 +0100 Subject: [PATCH 02/14] =?UTF-8?q?fix(ci):=20Renommage=20secrets=20pour=20?= =?UTF-8?q?=C3=A9viter=20restriction=20pr=C3=A9fixe=20FORGEJO=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forgejo n'autorise pas les noms de secrets commençant par FORGEJO_. Renommés : - FORGEJO_TOKEN -> GIT_TOKEN - FORGEJO_REPO_URL -> GIT_REPO_URL --- .forgejo/workflows/ci.yml | 2 +- .forgejo/workflows/deploy.yml | 12 ++++++------ .forgejo/workflows/destroy.yml | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 81492c6..07da0d5 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: TF_VAR_proxmox_token_id: ${{ secrets.PROXMOX_TOKEN_ID }} TF_VAR_proxmox_token_secret: ${{ secrets.PROXMOX_TOKEN_SECRET }} TF_VAR_ssh_public_key: ${{ secrets.SSH_PUBLIC_KEY }} - TF_VAR_forgejo_token: ${{ secrets.FORGEJO_TOKEN }} + TF_VAR_forgejo_token: ${{ secrets.GIT_TOKEN }} - name: Upload Terraform Plan if: github.event_name == 'push' && github.ref == 'refs/heads/main' diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 094f013..dc30fc5 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -28,8 +28,8 @@ jobs: proxmox_token_id = "${{ secrets.PROXMOX_TOKEN_ID }}" proxmox_token_secret = "${{ secrets.PROXMOX_TOKEN_SECRET }}" ssh_public_key = "${{ secrets.SSH_PUBLIC_KEY }}" - forgejo_token = "${{ secrets.FORGEJO_TOKEN }}" - forgejo_repo_url = "${{ secrets.FORGEJO_REPO_URL }}" + forgejo_token = "${{ secrets.GIT_TOKEN }}" + forgejo_repo_url = "${{ secrets.GIT_REPO_URL }}" k3s_version = "v1.28.5+k3s1" ubuntu_template = "ubuntu-2404-cloudinit" storage_pool = "linstor_storage" @@ -57,8 +57,8 @@ jobs: proxmox_token_id = "${{ secrets.PROXMOX_TOKEN_ID }}" proxmox_token_secret = "${{ secrets.PROXMOX_TOKEN_SECRET }}" ssh_public_key = "${{ secrets.SSH_PUBLIC_KEY }}" - forgejo_token = "${{ secrets.FORGEJO_TOKEN }}" - forgejo_repo_url = "${{ secrets.FORGEJO_REPO_URL }}" + forgejo_token = "${{ secrets.GIT_TOKEN }}" + forgejo_repo_url = "${{ secrets.GIT_REPO_URL }}" k3s_version = "v1.28.5+k3s1" ubuntu_template = "ubuntu-2404-cloudinit" storage_pool = "linstor_storage" @@ -86,8 +86,8 @@ jobs: proxmox_token_id = "${{ secrets.PROXMOX_TOKEN_ID }}" proxmox_token_secret = "${{ secrets.PROXMOX_TOKEN_SECRET }}" ssh_public_key = "${{ secrets.SSH_PUBLIC_KEY }}" - forgejo_token = "${{ secrets.FORGEJO_TOKEN }}" - forgejo_repo_url = "${{ secrets.FORGEJO_REPO_URL }}" + forgejo_token = "${{ secrets.GIT_TOKEN }}" + forgejo_repo_url = "${{ secrets.GIT_REPO_URL }}" k3s_version = "v1.28.5+k3s1" ubuntu_template = "ubuntu-2404-cloudinit" storage_pool = "linstor_storage" diff --git a/.forgejo/workflows/destroy.yml b/.forgejo/workflows/destroy.yml index 8063d91..5d1cc8a 100644 --- a/.forgejo/workflows/destroy.yml +++ b/.forgejo/workflows/destroy.yml @@ -40,8 +40,8 @@ jobs: proxmox_token_id = "${{ secrets.PROXMOX_TOKEN_ID }}" proxmox_token_secret = "${{ secrets.PROXMOX_TOKEN_SECRET }}" ssh_public_key = "${{ secrets.SSH_PUBLIC_KEY }}" - forgejo_token = "${{ secrets.FORGEJO_TOKEN }}" - forgejo_repo_url = "${{ secrets.FORGEJO_REPO_URL }}" + forgejo_token = "${{ secrets.GIT_TOKEN }}" + forgejo_repo_url = "${{ secrets.GIT_REPO_URL }}" EOF tofu init From c26289c262378a5ad1de0ba20523af2feb564ed3 Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 13 Nov 2025 19:45:17 +0100 Subject: [PATCH 03/14] =?UTF-8?q?fix(terraform):=20Mise=20=C3=A0=20jour=20?= =?UTF-8?q?ID=20token=20dans=20exemple=20de=20terraform=20vers=20opentofu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le fichier exemple avait root@pam!terraform en dur, ce qui écrasait la valeur secrète. Mis à jour pour correspondre au nom réel du token. --- terraform/terraform.tfvars.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example index 04d0dcc..7b80187 100644 --- a/terraform/terraform.tfvars.example +++ b/terraform/terraform.tfvars.example @@ -2,7 +2,7 @@ # Proxmox Configuration proxmox_api_url = "https://192.168.100.10:8006/api2/json" -proxmox_token_id = "root@pam!terraform" +proxmox_token_id = "root@pam!opentofu" proxmox_token_secret = "your-proxmox-token-secret" proxmox_tls_insecure = true From ae0f3754ad895929f767b3c339b27eecfaa6ea54 Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 13 Nov 2025 19:47:47 +0100 Subject: [PATCH 04/14] fix(ci): Utilisation variables environnement au lieu fichier tfvars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suppression copie terraform.tfvars.example qui écrasait valeurs secrètes. Utilisation maintenant exclusivement variables environnement TF_VAR_* pour injecter correctement secrets depuis Forgejo. --- .forgejo/workflows/ci.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 07da0d5..6960efd 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -42,17 +42,29 @@ jobs: echo "--- Planning $dir ---" ( cd "$dir" && \ - cp ../terraform.tfvars.example terraform.tfvars && \ tofu init && \ tofu plan -out="tfplan-$(basename $dir)" || echo "WARNING: Plan failed for $(basename $dir) - node may be unavailable" ) fi done env: + TF_VAR_proxmox_api_url: "https://192.168.100.10:8006/api2/json" TF_VAR_proxmox_token_id: ${{ secrets.PROXMOX_TOKEN_ID }} TF_VAR_proxmox_token_secret: ${{ secrets.PROXMOX_TOKEN_SECRET }} + TF_VAR_proxmox_tls_insecure: "true" TF_VAR_ssh_public_key: ${{ secrets.SSH_PUBLIC_KEY }} TF_VAR_forgejo_token: ${{ secrets.GIT_TOKEN }} + TF_VAR_forgejo_repo_url: ${{ secrets.GIT_REPO_URL }} + TF_VAR_k3s_version: "v1.28.5+k3s1" + TF_VAR_ubuntu_template: "ubuntu-2404-cloudinit" + TF_VAR_storage_pool: "linstor_storage" + TF_VAR_snippets_storage: "local" + TF_VAR_k3s_network_bridge: "k3s" + TF_VAR_k3s_gateway: "10.100.20.1" + TF_VAR_k3s_dns: '["10.100.20.1", "1.1.1.1"]' + TF_VAR_k3s_server_1_config: '{ ip = "10.100.20.10/24", cores = 6, memory = 12288, disk_size = "100G" }' + TF_VAR_k3s_server_2_config: '{ ip = "10.100.20.20/24", cores = 6, memory = 12288, disk_size = "100G" }' + TF_VAR_etcd_witness_config: '{ ip = "10.100.20.30/24", cores = 2, memory = 2048, disk_size = "20G" }' - name: Upload Terraform Plan if: github.event_name == 'push' && github.ref == 'refs/heads/main' From dc5fc28ff1614b15f1059273785ffa4fc6d8f85f Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 13 Nov 2025 19:52:52 +0100 Subject: [PATCH 05/14] fix(ci): Exclusion branche main du workflow CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Workflow CI s'exécute maintenant uniquement sur branches feature et PRs. Sur main, seul le workflow CD s'exécute (qui appelle CI en interne). Ceci évite les exécutions CI dupliquées. --- .forgejo/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 6960efd..d484eb8 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -2,7 +2,9 @@ name: CI - Validation on: push: - branches: ['**'] # All branches + branches: + - '**' + - '!main' # Exclude main branch (CD workflow handles it) pull_request: jobs: From 83f9b4def87a8f5fc8c0d362bd54783988714b81 Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 13 Nov 2025 19:56:13 +0100 Subject: [PATCH 06/14] =?UTF-8?q?fix(ci):=20Ajout=20trigger=20workflow=5Fc?= =?UTF-8?q?all=20pour=20int=C3=A9gration=20CD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le workflow CI nécessite workflow_call pour être appelable par workflow CD. Sans cela, le workflow CD ne peut pas invoquer CI comme workflow réutilisable. --- .forgejo/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index d484eb8..87bf0c0 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -6,6 +6,7 @@ on: - '**' - '!main' # Exclude main branch (CD workflow handles it) pull_request: + workflow_call: # Allow this workflow to be called by other workflows jobs: ci-terraform: From 8687665946f58b4bb5579a4e5e4d41d874323e92 Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 13 Nov 2025 20:00:53 +0100 Subject: [PATCH 07/14] =?UTF-8?q?fix(cd):=20Remplacement=20workflow=20r?= =?UTF-8?q?=C3=A9utilisable=20par=20jobs=20CI=20inline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forgejo ne supporte pas complètement les workflows réutilisables (uses:). Duplication job validation Terraform directement dans workflow CD pour éviter état bloquant. --- .forgejo/workflows/deploy.yml | 69 +++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index dc30fc5..ba57729 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -7,16 +7,71 @@ on: workflow_dispatch: # Allow manual trigger jobs: - # Run CI first - ci: - uses: ./.forgejo/workflows/ci.yml - secrets: inherit + # Run Terraform validation first + ci-terraform: + name: Terraform Validation + runs-on: self-hosted + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup OpenTofu + run: | + if ! command -v tofu &> /dev/null; then + curl -fsSL https://get.opentofu.org/install-opentofu.sh | bash -s -- --install-method standalone --opentofu-version 1.10.7 + fi + + - name: Terraform Format Check + run: | + cd terraform + tofu fmt -check -recursive + continue-on-error: false + + - name: Terraform Validate + run: | + for dir in terraform/pve*; do + if [ -d "$dir" ]; then + echo "--- Validating $dir ---" + (cd "$dir" && tofu init -backend=false && tofu validate) + fi + done + + - name: Terraform Plan + run: | + for dir in terraform/pve*; do + if [ -d "$dir" ]; then + echo "--- Planning $dir ---" + ( + cd "$dir" && \ + tofu init && \ + tofu plan || echo "WARNING: Plan failed for $(basename $dir) - node may be unavailable" + ) + fi + done + env: + TF_VAR_proxmox_api_url: "https://192.168.100.10:8006/api2/json" + TF_VAR_proxmox_token_id: ${{ secrets.PROXMOX_TOKEN_ID }} + TF_VAR_proxmox_token_secret: ${{ secrets.PROXMOX_TOKEN_SECRET }} + TF_VAR_proxmox_tls_insecure: "true" + TF_VAR_ssh_public_key: ${{ secrets.SSH_PUBLIC_KEY }} + TF_VAR_forgejo_token: ${{ secrets.GIT_TOKEN }} + TF_VAR_forgejo_repo_url: ${{ secrets.GIT_REPO_URL }} + TF_VAR_k3s_version: "v1.28.5+k3s1" + TF_VAR_ubuntu_template: "ubuntu-2404-cloudinit" + TF_VAR_storage_pool: "linstor_storage" + TF_VAR_snippets_storage: "local" + TF_VAR_k3s_network_bridge: "k3s" + TF_VAR_k3s_gateway: "10.100.20.1" + TF_VAR_k3s_dns: '["10.100.20.1", "1.1.1.1"]' + TF_VAR_k3s_server_1_config: '{ ip = "10.100.20.10/24", cores = 6, memory = 12288, disk_size = "100G" }' + TF_VAR_k3s_server_2_config: '{ ip = "10.100.20.20/24", cores = 6, memory = 12288, disk_size = "100G" }' + TF_VAR_etcd_witness_config: '{ ip = "10.100.20.30/24", cores = 2, memory = 2048, disk_size = "20G" }' # Deploy infrastructure in parallel deploy-pve1: name: Deploy on pve1 runs-on: self-hosted - needs: ci + needs: ci-terraform continue-on-error: true steps: - name: Checkout code @@ -45,7 +100,7 @@ jobs: deploy-pve2: name: Deploy on pve2 runs-on: self-hosted - needs: ci + needs: ci-terraform continue-on-error: true steps: - name: Checkout code @@ -74,7 +129,7 @@ jobs: deploy-pve3: name: Deploy on pve3 runs-on: self-hosted - needs: ci + needs: ci-terraform continue-on-error: true steps: - name: Checkout code From 8c738e9e19732dbf2ea51e90299285f4db977092 Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Thu, 13 Nov 2025 20:03:49 +0100 Subject: [PATCH 08/14] =?UTF-8?q?fix(cd):=20Ajout=20=C3=A9tape=20setup=20O?= =?UTF-8?q?penTofu=20dans=20tous=20les=20jobs=20d=C3=A9ploiement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jobs de déploiement échouaient avec 'tofu: commande introuvable'. Ajout étape Setup OpenTofu aux jobs deploy-pve1, deploy-pve2, and deploy-pve3 jobs. --- .forgejo/workflows/deploy.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index ba57729..302a320 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -76,6 +76,11 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + - name: Setup OpenTofu + run: | + if ! command -v tofu &> /dev/null; then + curl -fsSL https://get.opentofu.org/install-opentofu.sh | bash -s -- --install-method standalone --opentofu-version 1.10.7 + fi - name: Terraform Apply on pve1 run: | cd terraform/pve1 @@ -105,6 +110,11 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + - name: Setup OpenTofu + run: | + if ! command -v tofu &> /dev/null; then + curl -fsSL https://get.opentofu.org/install-opentofu.sh | bash -s -- --install-method standalone --opentofu-version 1.10.7 + fi - name: Terraform Apply on pve2 run: | cd terraform/pve2 @@ -134,6 +144,11 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + - name: Setup OpenTofu + run: | + if ! command -v tofu &> /dev/null; then + curl -fsSL https://get.opentofu.org/install-opentofu.sh | bash -s -- --install-method standalone --opentofu-version 1.10.7 + fi - name: Terraform Apply on pve3 run: | cd terraform/pve3 From 155de75fbf77c1a86f2dd61998d5140858d50e11 Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Wed, 26 Nov 2025 19:31:03 +0100 Subject: [PATCH 09/14] =?UTF-8?q?feat(terraform):=20Mise=20=C3=A0=20jour?= =?UTF-8?q?=20provider=20Proxmox=20v3.0.2-rc05?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mettre à jour version provider et ajuster syntaxe ressources pour compatibilité. --- terraform/pve1/main.tf | 24 ++++++++++++++---------- terraform/pve2/main.tf | 24 ++++++++++++++---------- terraform/pve3/main.tf | 24 ++++++++++++++---------- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/terraform/pve1/main.tf b/terraform/pve1/main.tf index ee89a30..8db3b2a 100644 --- a/terraform/pve1/main.tf +++ b/terraform/pve1/main.tf @@ -4,7 +4,7 @@ terraform { required_providers { proxmox = { source = "telmate/proxmox" - version = "~> 2.9" + version = "3.0.2-rc05" } local = { source = "hashicorp/local" @@ -20,32 +20,36 @@ provider "proxmox" { pm_tls_insecure = var.proxmox_tls_insecure } -# K3s Server VM on pve1 +# K3s Server VM on acemagician resource "proxmox_vm_qemu" "k3s_server_1" { name = "k3s-server-1" - target_node = "pve1" + target_node = "acemagician" clone = var.ubuntu_template - cores = var.k3s_server_1_config.cores - sockets = 1 - memory = var.k3s_server_1_config.memory - agent = 1 + cpu { + cores = var.k3s_server_1_config.cores + sockets = 1 + } + + memory = var.k3s_server_1_config.memory + agent = 1 boot = "order=scsi0" scsihw = "virtio-scsi-single" onboot = true network { + id = 0 model = "virtio" bridge = var.k3s_network_bridge } disk { - slot = 0 + slot = "scsi0" size = var.k3s_server_1_config.disk_size - type = "scsi" + type = "disk" storage = var.storage_pool - iothread = 1 + iothread = true } ipconfig0 = "ip=${var.k3s_server_1_config.ip},gw=${var.k3s_gateway}" diff --git a/terraform/pve2/main.tf b/terraform/pve2/main.tf index 36975b1..047af38 100644 --- a/terraform/pve2/main.tf +++ b/terraform/pve2/main.tf @@ -4,7 +4,7 @@ terraform { required_providers { proxmox = { source = "telmate/proxmox" - version = "~> 2.9" + version = "3.0.2-rc05" } local = { source = "hashicorp/local" @@ -20,32 +20,36 @@ provider "proxmox" { pm_tls_insecure = var.proxmox_tls_insecure } -# K3s Server VM on pve2 +# K3s Server VM on elitedesk resource "proxmox_vm_qemu" "k3s_server_2" { name = "k3s-server-2" - target_node = "pve2" + target_node = "elitedesk" clone = var.ubuntu_template - cores = var.k3s_server_2_config.cores - sockets = 1 - memory = var.k3s_server_2_config.memory - agent = 1 + cpu { + cores = var.k3s_server_2_config.cores + sockets = 1 + } + + memory = var.k3s_server_2_config.memory + agent = 1 boot = "order=scsi0" scsihw = "virtio-scsi-single" onboot = true network { + id = 0 model = "virtio" bridge = var.k3s_network_bridge } disk { - slot = 0 + slot = "scsi0" size = var.k3s_server_2_config.disk_size - type = "scsi" + type = "disk" storage = var.storage_pool - iothread = 1 + iothread = true } ipconfig0 = "ip=${var.k3s_server_2_config.ip},gw=${var.k3s_gateway}" diff --git a/terraform/pve3/main.tf b/terraform/pve3/main.tf index 323f68e..04cab29 100644 --- a/terraform/pve3/main.tf +++ b/terraform/pve3/main.tf @@ -4,7 +4,7 @@ terraform { required_providers { proxmox = { source = "telmate/proxmox" - version = "~> 2.9" + version = "3.0.2-rc05" } local = { source = "hashicorp/local" @@ -20,32 +20,36 @@ provider "proxmox" { pm_tls_insecure = var.proxmox_tls_insecure } -# etcd Witness VM on pve3 +# etcd Witness VM on thinkpad resource "proxmox_vm_qemu" "etcd_witness" { name = "etcd-witness" - target_node = "pve3" + target_node = "thinkpad" clone = var.ubuntu_template - cores = var.etcd_witness_config.cores - sockets = 1 - memory = var.etcd_witness_config.memory - agent = 1 + cpu { + cores = var.etcd_witness_config.cores + sockets = 1 + } + + memory = var.etcd_witness_config.memory + agent = 1 boot = "order=scsi0" scsihw = "virtio-scsi-single" onboot = true network { + id = 0 model = "virtio" bridge = var.k3s_network_bridge } disk { - slot = 0 + slot = "scsi0" size = var.etcd_witness_config.disk_size - type = "scsi" + type = "disk" storage = var.storage_pool - iothread = 1 + iothread = true } ipconfig0 = "ip=${var.etcd_witness_config.ip},gw=${var.k3s_gateway}" From 5f6df07fbe3697ca857c18dc407e2e8506723af8 Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Wed, 26 Nov 2025 19:27:20 +0100 Subject: [PATCH 10/14] =?UTF-8?q?fix(terraform):=20Configuration=20n=C5=93?= =?UTF-8?q?uds=20cluster=20et=20stockage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .forgejo/workflows/deploy.yml | 71 ++++++++++++++++++----------------- terraform/pve1/main.tf | 3 +- terraform/pve1/variables.tf | 6 +++ terraform/pve2/main.tf | 3 +- terraform/pve2/variables.tf | 6 +++ terraform/pve3/main.tf | 3 +- terraform/pve3/variables.tf | 6 +++ 7 files changed, 61 insertions(+), 37 deletions(-) diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 302a320..c57c0e1 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -90,14 +90,15 @@ jobs: ssh_public_key = "${{ secrets.SSH_PUBLIC_KEY }}" forgejo_token = "${{ secrets.GIT_TOKEN }}" forgejo_repo_url = "${{ secrets.GIT_REPO_URL }}" - k3s_version = "v1.28.5+k3s1" - ubuntu_template = "ubuntu-2404-cloudinit" - storage_pool = "linstor_storage" - snippets_storage = "local" - k3s_network_bridge = "k3s" - k3s_gateway = "10.100.20.1" - k3s_dns = ["10.100.20.1", "1.1.1.1"] - k3s_server_1_config = { ip = "10.100.20.10/24", cores = 6, memory = 12288, disk_size = "100G" } + k3s_version = "v1.28.5+k3s1" + ubuntu_template = "ubuntu-2404-cloudinit" + storage_pool = "linstor_storage" + k3s_server_1_storage_pool = "linstor_storage" + snippets_storage = "local" + k3s_network_bridge = "k3s" + k3s_gateway = "10.100.20.1" + k3s_dns = ["10.100.20.1", "1.1.1.1"] + k3s_server_1_config = { ip = "10.100.20.10/24", cores = 6, memory = 12288, disk_size = "100G" } EOF tofu init tofu apply -auto-approve @@ -119,19 +120,20 @@ jobs: run: | cd terraform/pve2 cat > terraform.tfvars < terraform.tfvars < Date: Wed, 26 Nov 2025 19:41:52 +0100 Subject: [PATCH 11/14] =?UTF-8?q?fix(terraform):=20VMID=20fixe=20pour=20VM?= =?UTF-8?q?s=20afin=20=C3=A9viter=20duplication?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assigner VMID spécifique à chaque VM : - k3s-server-1: 1000 - k3s-server-2: 1001 - etcd-witness: 1002 --- terraform/pve1/main.tf | 1 + terraform/pve2/main.tf | 1 + terraform/pve3/main.tf | 1 + 3 files changed, 3 insertions(+) diff --git a/terraform/pve1/main.tf b/terraform/pve1/main.tf index 7c9ff02..285e8a8 100644 --- a/terraform/pve1/main.tf +++ b/terraform/pve1/main.tf @@ -22,6 +22,7 @@ provider "proxmox" { # K3s Server VM on acemagician resource "proxmox_vm_qemu" "k3s_server_1" { + vmid = 1000 name = "k3s-server-1" target_node = "acemagician" clone = var.ubuntu_template diff --git a/terraform/pve2/main.tf b/terraform/pve2/main.tf index 830c2f2..c0b4afe 100644 --- a/terraform/pve2/main.tf +++ b/terraform/pve2/main.tf @@ -22,6 +22,7 @@ provider "proxmox" { # K3s Server VM on elitedesk resource "proxmox_vm_qemu" "k3s_server_2" { + vmid = 1001 name = "k3s-server-2" target_node = "elitedesk" clone = var.ubuntu_template diff --git a/terraform/pve3/main.tf b/terraform/pve3/main.tf index 9fcdde7..a1ab8f5 100644 --- a/terraform/pve3/main.tf +++ b/terraform/pve3/main.tf @@ -22,6 +22,7 @@ provider "proxmox" { # etcd Witness VM on thinkpad resource "proxmox_vm_qemu" "etcd_witness" { + vmid = 1002 name = "etcd-witness" target_node = "thinkpad" clone = var.ubuntu_template From 3b5f1fc2d22eda7bcb5b30dca91719f2e07bf59a Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Tue, 9 Dec 2025 11:55:19 +0100 Subject: [PATCH 12/14] =?UTF-8?q?feat:=20Configuration=20stockage=20local?= =?UTF-8?q?=20et=20token=20K3S=20partag=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Passage stockage local-nvme pour acemagician et elitedesk (40G) - Token K3S partagé via cloud-init pour cluster HA - Configuration FluxCD avec GitRepository Forgejo - Déploiement Hello World via FluxCD - Manifestes Kubernetes pour application demo --- .forgejo/workflows/deploy.yml | 25 +++---- ansible/group_vars/all.yml | 13 ---- ansible/roles/etcd-witness/tasks/main.yml | 18 ++--- .../roles/k3s-server/files/k3s-pre-reboot.sh | 6 -- ansible/roles/k3s-server/tasks/flux.yml | 72 +++++++++++++++++-- ansible/roles/k3s-server/tasks/main.yml | 27 ++++--- ansible/site.yml | 7 -- k8s/hello-world/deployment.yaml | 37 ++++++++++ k8s/hello-world/namespace.yaml | 4 ++ k8s/hello-world/service.yaml | 13 ++++ terraform/pve1/cloud-init.tf | 5 +- terraform/pve1/variables.tf | 10 ++- terraform/pve2/cloud-init.tf | 5 +- terraform/pve2/variables.tf | 10 ++- terraform/pve3/cloud-init.tf | 5 +- terraform/pve3/variables.tf | 6 ++ terraform/terraform.tfvars.example | 14 +--- 17 files changed, 193 insertions(+), 84 deletions(-) create mode 100644 k8s/hello-world/deployment.yaml create mode 100644 k8s/hello-world/namespace.yaml create mode 100644 k8s/hello-world/service.yaml diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index c57c0e1..45f0716 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -4,10 +4,9 @@ on: push: branches: - main - workflow_dispatch: # Allow manual trigger + workflow_dispatch: jobs: - # Run Terraform validation first ci-terraform: name: Terraform Validation runs-on: self-hosted @@ -63,11 +62,11 @@ jobs: TF_VAR_k3s_network_bridge: "k3s" TF_VAR_k3s_gateway: "10.100.20.1" TF_VAR_k3s_dns: '["10.100.20.1", "1.1.1.1"]' - TF_VAR_k3s_server_1_config: '{ ip = "10.100.20.10/24", cores = 6, memory = 12288, disk_size = "100G" }' - TF_VAR_k3s_server_2_config: '{ ip = "10.100.20.20/24", cores = 6, memory = 12288, disk_size = "100G" }' + TF_VAR_k3s_token: ${{ secrets.K3S_TOKEN }} + TF_VAR_k3s_server_1_config: '{ ip = "10.100.20.10/24", cores = 6, memory = 12288, disk_size = "40G" }' + TF_VAR_k3s_server_2_config: '{ ip = "10.100.20.20/24", cores = 6, memory = 12288, disk_size = "40G" }' TF_VAR_etcd_witness_config: '{ ip = "10.100.20.30/24", cores = 2, memory = 2048, disk_size = "20G" }' - # Deploy infrastructure in parallel deploy-pve1: name: Deploy on pve1 runs-on: self-hosted @@ -91,14 +90,15 @@ jobs: forgejo_token = "${{ secrets.GIT_TOKEN }}" forgejo_repo_url = "${{ secrets.GIT_REPO_URL }}" k3s_version = "v1.28.5+k3s1" + k3s_token = "${{ secrets.K3S_TOKEN }}" ubuntu_template = "ubuntu-2404-cloudinit" storage_pool = "linstor_storage" - k3s_server_1_storage_pool = "linstor_storage" + k3s_server_1_storage_pool = "local-nvme" snippets_storage = "local" k3s_network_bridge = "k3s" k3s_gateway = "10.100.20.1" k3s_dns = ["10.100.20.1", "1.1.1.1"] - k3s_server_1_config = { ip = "10.100.20.10/24", cores = 6, memory = 12288, disk_size = "100G" } + k3s_server_1_config = { ip = "10.100.20.10/24", cores = 6, memory = 12288, disk_size = "40G" } EOF tofu init tofu apply -auto-approve @@ -126,14 +126,15 @@ jobs: forgejo_token = "${{ secrets.GIT_TOKEN }}" forgejo_repo_url = "${{ secrets.GIT_REPO_URL }}" k3s_version = "v1.28.5+k3s1" + k3s_token = "${{ secrets.K3S_TOKEN }}" ubuntu_template = "ubuntu-2404-cloudinit" storage_pool = "linstor_storage" - k3s_server_2_storage_pool = "linstor_storage" + k3s_server_2_storage_pool = "local-nvme" snippets_storage = "local" k3s_network_bridge = "k3s" k3s_gateway = "10.100.20.1" k3s_dns = ["10.100.20.1", "1.1.1.1"] - k3s_server_2_config = { ip = "10.100.20.20/24", cores = 6, memory = 12288, disk_size = "100G" } + k3s_server_2_config = { ip = "10.100.20.20/24", cores = 6, memory = 12288, disk_size = "40G" } EOF tofu init tofu apply -auto-approve @@ -161,6 +162,7 @@ jobs: forgejo_token = "${{ secrets.GIT_TOKEN }}" forgejo_repo_url = "${{ secrets.GIT_REPO_URL }}" k3s_version = "v1.28.5+k3s1" + k3s_token = "${{ secrets.K3S_TOKEN }}" ubuntu_template = "ubuntu-2404-cloudinit" storage_pool = "linstor_storage" etcd_witness_storage_pool = "local-lvm" @@ -192,13 +194,12 @@ jobs: - name: Wait for K3s cluster run: | echo "Waiting for K3s cluster to be ready..." - sleep 300 # Wait 5 minutes for ansible-pull to configure K3s - - name: Check cluster status (optional) + sleep 300 + - name: Check cluster status run: | echo "Cluster validation completed" continue-on-error: true - # Notify on completion notify: name: Deployment Notification runs-on: self-hosted diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index 7ac4183..e766079 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -1,44 +1,32 @@ --- -# Global variables for all nodes - -# K3s Configuration k3s_version: "v1.28.5+k3s1" k3s_install_url: "https://get.k3s.io" -# K3s Server Configuration k3s_server_1_ip: "10.100.20.10" k3s_server_2_ip: "10.100.20.20" k3s_witness_ip: "10.100.20.30" -# K3s token (shared between servers) -# In production, this should be stored in a vault k3s_token_file: "/etc/rancher/k3s/token" -# Network Configuration pod_cidr: "10.42.0.0/16" service_cidr: "10.43.0.0/16" cluster_dns: "10.43.0.10" -# System Configuration timezone: "Europe/Paris" swap_enabled: false -# Unattended Upgrades Configuration unattended_upgrades_enabled: true unattended_upgrades_automatic_reboot: true unattended_upgrades_automatic_reboot_with_users: false -# Reboot schedule (staggered to maintain availability) reboot_schedule: k3s-server-1: "02:00" k3s-server-2: "04:00" etcd-witness: "06:00" -# FluxCD Configuration flux_version: "v2.2.0" flux_namespace: "flux-system" -# System packages to install on all nodes common_packages: - curl - wget @@ -52,7 +40,6 @@ common_packages: - python3 - python3-pip -# Kernel parameters for K3s sysctl_config: net.bridge.bridge-nf-call-iptables: 1 net.bridge.bridge-nf-call-ip6tables: 1 diff --git a/ansible/roles/etcd-witness/tasks/main.yml b/ansible/roles/etcd-witness/tasks/main.yml index efd1a89..b46e079 100644 --- a/ansible/roles/etcd-witness/tasks/main.yml +++ b/ansible/roles/etcd-witness/tasks/main.yml @@ -1,19 +1,19 @@ --- -# etcd witness node configuration -# This node participates in etcd quorum but does not run K8s workloads - - name: Check if K3s is already installed stat: path: /usr/local/bin/k3s register: k3s_binary -- name: Get K3s token from first server +- name: Load K3s token from environment set_fact: - k3s_token: >- - {{ - lookup('file', k3s_token_file, errors='ignore') - | default('PLACEHOLDER') - }} + k3s_token: "{{ lookup('env', 'K3S_TOKEN') }}" + +- name: Wait for first server API + wait_for: + host: "{{ k3s_server_1_ip }}" + port: 6443 + delay: 60 + timeout: 900 - name: Install K3s as server (witness mode) shell: > diff --git a/ansible/roles/k3s-server/files/k3s-pre-reboot.sh b/ansible/roles/k3s-server/files/k3s-pre-reboot.sh index e7538db..aa359a0 100644 --- a/ansible/roles/k3s-server/files/k3s-pre-reboot.sh +++ b/ansible/roles/k3s-server/files/k3s-pre-reboot.sh @@ -1,19 +1,13 @@ #!/bin/bash -# K3s pre-reboot script -# Drains the node before system reboot to migrate workloads gracefully - set -e -# Only run if k3s is active if systemctl is-active --quiet k3s; then NODE_NAME=$(hostname) echo "$(date): Starting pre-reboot drain for node $NODE_NAME" | logger -t k3s-pre-reboot - # Set KUBECONFIG export KUBECONFIG=/etc/rancher/k3s/k3s.yaml - # Drain the node (migrate pods to other nodes) /usr/local/bin/k3s kubectl drain "$NODE_NAME" \ --ignore-daemonsets \ --delete-emptydir-data \ diff --git a/ansible/roles/k3s-server/tasks/flux.yml b/ansible/roles/k3s-server/tasks/flux.yml index f7dd1a7..ba8e84a 100644 --- a/ansible/roles/k3s-server/tasks/flux.yml +++ b/ansible/roles/k3s-server/tasks/flux.yml @@ -1,6 +1,4 @@ --- -# Install and configure FluxCD - - name: Check if flux is already installed command: k3s kubectl get namespace {{ flux_namespace }} register: flux_installed @@ -44,9 +42,73 @@ changed_when: false when: flux_installed.rc != 0 +- name: Load Forgejo token from environment + set_fact: + forgejo_token: "{{ lookup('env', 'FORGEJO_TOKEN') }}" + forgejo_repo_url: "{{ lookup('env', 'REPO_URL') }}" + +- name: Create Forgejo secret for FluxCD + shell: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + k3s kubectl create secret generic forgejo-auth \ + --namespace={{ flux_namespace }} \ + --from-literal=username=git \ + --from-literal=password={{ forgejo_token }} \ + --dry-run=client -o yaml | k3s kubectl apply -f - + when: flux_installed.rc != 0 + +- name: Create GitRepository manifest + copy: + dest: /tmp/gitrepository.yaml + content: | + apiVersion: source.toolkit.fluxcd.io/v1 + kind: GitRepository + metadata: + name: infra + namespace: {{ flux_namespace }} + spec: + interval: 1m + url: {{ forgejo_repo_url }} + ref: + branch: main + secretRef: + name: forgejo-auth + mode: '0644' + when: flux_installed.rc != 0 + +- name: Apply GitRepository + shell: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + k3s kubectl apply -f /tmp/gitrepository.yaml + when: flux_installed.rc != 0 + +- name: Create Kustomization manifest + copy: + dest: /tmp/kustomization.yaml + content: | + apiVersion: kustomize.toolkit.fluxcd.io/v1 + kind: Kustomization + metadata: + name: apps + namespace: {{ flux_namespace }} + spec: + interval: 1m + sourceRef: + kind: GitRepository + name: infra + path: ./k8s + prune: true + wait: true + mode: '0644' + when: flux_installed.rc != 0 + +- name: Apply Kustomization + shell: | + export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + k3s kubectl apply -f /tmp/kustomization.yaml + when: flux_installed.rc != 0 + - name: Display FluxCD installation status debug: - msg: >- - FluxCD installed successfully. - Configure GitRepository in kubernetes/flux-system/ + msg: "FluxCD configured to sync from {{ forgejo_repo_url }}" when: flux_installed.rc != 0 diff --git a/ansible/roles/k3s-server/tasks/main.yml b/ansible/roles/k3s-server/tasks/main.yml index 4ddc3d4..83a50c6 100644 --- a/ansible/roles/k3s-server/tasks/main.yml +++ b/ansible/roles/k3s-server/tasks/main.yml @@ -1,6 +1,4 @@ --- -# K3s server installation and configuration - - name: Check if K3s is already installed stat: path: /usr/local/bin/k3s @@ -17,10 +15,15 @@ set_fact: is_first_server: "{{ ansible_default_ipv4.address == k3s_server_1_ip }}" +- name: Load K3s token from environment + set_fact: + k3s_token: "{{ lookup('env', 'K3S_TOKEN') }}" + - name: Install K3s on first server (cluster-init) shell: > curl -sfL {{ k3s_install_url }} | INSTALL_K3S_VERSION="{{ k3s_version }}" + K3S_TOKEN="{{ k3s_token }}" sh -s - server --cluster-init --tls-san {{ k3s_server_1_ip }} @@ -44,17 +47,13 @@ timeout: 300 when: is_first_server -- name: Get K3s token from first server - slurp: - src: /var/lib/rancher/k3s/server/node-token - register: k3s_token_encoded - when: is_first_server - run_once: true - -- name: Save K3s token - set_fact: - k3s_token: "{{ k3s_token_encoded.content | b64decode | trim }}" - when: is_first_server +- name: Wait for first server API (second server) + wait_for: + host: "{{ k3s_server_1_ip }}" + port: 6443 + delay: 30 + timeout: 600 + when: not is_first_server - name: Install K3s on second server (join cluster) shell: > @@ -62,7 +61,7 @@ INSTALL_K3S_VERSION="{{ k3s_version }}" sh -s - server --server https://{{ k3s_server_1_ip }}:6443 - --token {{ k3s_token | default('PLACEHOLDER') }} + --token {{ k3s_token }} --tls-san {{ k3s_server_2_ip }} --write-kubeconfig-mode 644 --disable traefik diff --git a/ansible/site.yml b/ansible/site.yml index 51ceac8..92859c0 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -1,14 +1,10 @@ --- -# Main playbook for K3s GitOps infrastructure -# This playbook is executed by ansible-pull on each VM - - name: Configure K3s Infrastructure hosts: localhost connection: local become: true vars: - # Read node role from file created by cloud-init node_role: >- {{ lookup('file', '/etc/node-role', errors='ignore') @@ -34,14 +30,11 @@ cache_valid_time: 3600 roles: - # Common role applies to all nodes - role: common - # K3s server role (server + worker) - role: k3s-server when: node_role == 'server' - # etcd witness role (etcd only, no k8s workloads) - role: etcd-witness when: node_role == 'witness' diff --git a/k8s/hello-world/deployment.yaml b/k8s/hello-world/deployment.yaml new file mode 100644 index 0000000..ea03ea8 --- /dev/null +++ b/k8s/hello-world/deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hello-world + namespace: demo +spec: + replicas: 3 + selector: + matchLabels: + app: hello-world + template: + metadata: + labels: + app: hello-world + spec: + containers: + - name: hello-world + image: bashofmann/rancher-demo:1.0.0 + imagePullPolicy: Always + resources: + requests: + memory: "12Mi" + cpu: "2m" + ports: + - containerPort: 8080 + name: web + env: + - name: COW_COLOR + value: purple + readinessProbe: + httpGet: + path: / + port: web + livenessProbe: + httpGet: + path: / + port: web diff --git a/k8s/hello-world/namespace.yaml b/k8s/hello-world/namespace.yaml new file mode 100644 index 0000000..18434a6 --- /dev/null +++ b/k8s/hello-world/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: demo diff --git a/k8s/hello-world/service.yaml b/k8s/hello-world/service.yaml new file mode 100644 index 0000000..56ec09c --- /dev/null +++ b/k8s/hello-world/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: hello-world-service + namespace: demo +spec: + type: LoadBalancer + selector: + app: hello-world + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 diff --git a/terraform/pve1/cloud-init.tf b/terraform/pve1/cloud-init.tf index 3479f34..b5ee9ed 100644 --- a/terraform/pve1/cloud-init.tf +++ b/terraform/pve1/cloud-init.tf @@ -27,6 +27,9 @@ locals { #!/bin/bash set -e source /etc/ansible-pull.conf + export K3S_TOKEN + export FORGEJO_TOKEN + export REPO_URL WORK_DIR="/var/lib/ansible-local" mkdir -p $WORK_DIR cd $WORK_DIR @@ -48,7 +51,7 @@ locals { }, { path = "/etc/ansible-pull.conf" - content = "REPO_URL=${var.forgejo_repo_url}\nFORGEJO_TOKEN=${var.forgejo_token}\nK3S_VERSION=${var.k3s_version}" + content = "REPO_URL=${var.forgejo_repo_url}\nFORGEJO_TOKEN=${var.forgejo_token}\nK3S_VERSION=${var.k3s_version}\nK3S_TOKEN=${var.k3s_token}" permissions = "0600" }, { diff --git a/terraform/pve1/variables.tf b/terraform/pve1/variables.tf index d746444..d7ed579 100644 --- a/terraform/pve1/variables.tf +++ b/terraform/pve1/variables.tf @@ -54,9 +54,9 @@ variable "storage_pool" { } variable "k3s_server_1_storage_pool" { - description = "Storage pool for k3s-server-1 disk (linstor_storage for HA)" + description = "Storage pool for k3s-server-1 disk (local-nvme for acemagician)" type = string - default = "linstor_storage" + default = "local-nvme" } variable "snippets_storage" { @@ -88,3 +88,9 @@ variable "k3s_server_1_config" { disk_size = string }) } + +variable "k3s_token" { + description = "K3s cluster token" + type = string + sensitive = true +} diff --git a/terraform/pve2/cloud-init.tf b/terraform/pve2/cloud-init.tf index 2eab5cb..0931fc7 100644 --- a/terraform/pve2/cloud-init.tf +++ b/terraform/pve2/cloud-init.tf @@ -27,6 +27,9 @@ locals { #!/bin/bash set -e source /etc/ansible-pull.conf + export K3S_TOKEN + export FORGEJO_TOKEN + export REPO_URL WORK_DIR="/var/lib/ansible-local" mkdir -p $WORK_DIR cd $WORK_DIR @@ -48,7 +51,7 @@ locals { }, { path = "/etc/ansible-pull.conf" - content = "REPO_URL=${var.forgejo_repo_url}\nFORGEJO_TOKEN=${var.forgejo_token}\nK3S_VERSION=${var.k3s_version}" + content = "REPO_URL=${var.forgejo_repo_url}\nFORGEJO_TOKEN=${var.forgejo_token}\nK3S_VERSION=${var.k3s_version}\nK3S_TOKEN=${var.k3s_token}" permissions = "0600" }, { diff --git a/terraform/pve2/variables.tf b/terraform/pve2/variables.tf index 5983230..7ba47ea 100644 --- a/terraform/pve2/variables.tf +++ b/terraform/pve2/variables.tf @@ -54,9 +54,9 @@ variable "storage_pool" { } variable "k3s_server_2_storage_pool" { - description = "Storage pool for k3s-server-2 disk (linstor_storage for HA)" + description = "Storage pool for k3s-server-2 disk (local-nvme for elitedesk)" type = string - default = "linstor_storage" + default = "local-nvme" } variable "snippets_storage" { @@ -88,3 +88,9 @@ variable "k3s_server_2_config" { disk_size = string }) } + +variable "k3s_token" { + description = "K3s cluster token" + type = string + sensitive = true +} diff --git a/terraform/pve3/cloud-init.tf b/terraform/pve3/cloud-init.tf index b9e2036..e61efc4 100644 --- a/terraform/pve3/cloud-init.tf +++ b/terraform/pve3/cloud-init.tf @@ -27,6 +27,9 @@ locals { #!/bin/bash set -e source /etc/ansible-pull.conf + export K3S_TOKEN + export FORGEJO_TOKEN + export REPO_URL WORK_DIR="/var/lib/ansible-local" mkdir -p $WORK_DIR cd $WORK_DIR @@ -48,7 +51,7 @@ locals { }, { path = "/etc/ansible-pull.conf" - content = "REPO_URL=${var.forgejo_repo_url}\nFORGEJO_TOKEN=${var.forgejo_token}\nK3S_VERSION=${var.k3s_version}" + content = "REPO_URL=${var.forgejo_repo_url}\nFORGEJO_TOKEN=${var.forgejo_token}\nK3S_VERSION=${var.k3s_version}\nK3S_TOKEN=${var.k3s_token}" permissions = "0600" }, { diff --git a/terraform/pve3/variables.tf b/terraform/pve3/variables.tf index 4d3d7a6..e2e4d58 100644 --- a/terraform/pve3/variables.tf +++ b/terraform/pve3/variables.tf @@ -88,3 +88,9 @@ variable "etcd_witness_config" { disk_size = string }) } + +variable "k3s_token" { + description = "K3s cluster token" + type = string + sensitive = true +} diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example index 7b80187..06ffcf7 100644 --- a/terraform/terraform.tfvars.example +++ b/terraform/terraform.tfvars.example @@ -1,44 +1,36 @@ -# Copy this file to terraform.tfvars and fill in your values - -# Proxmox Configuration proxmox_api_url = "https://192.168.100.10:8006/api2/json" proxmox_token_id = "root@pam!opentofu" proxmox_token_secret = "your-proxmox-token-secret" proxmox_tls_insecure = true -# SSH Access ssh_public_key = "ssh-ed25519 AAAAC3... your-email@example.com" -# Forgejo Configuration forgejo_token = "your-forgejo-token" forgejo_repo_url = "ssh://git@forgejo.tellserv.fr:222/Tellsanguis/infra.git" -# K3s Version k3s_version = "v1.28.5+k3s1" +k3s_token = "your-k3s-cluster-token" -# Template and Storage ubuntu_template = "ubuntu-2404-cloudinit" storage_pool = "linstor_storage" snippets_storage = "local" -# Network k3s_network_bridge = "k3s" k3s_gateway = "10.100.20.1" k3s_dns = ["10.100.20.1", "1.1.1.1"] -# VM Configurations k3s_server_1_config = { ip = "10.100.20.10/24" cores = 6 memory = 12288 - disk_size = "100G" + disk_size = "40G" } k3s_server_2_config = { ip = "10.100.20.20/24" cores = 6 memory = 12288 - disk_size = "100G" + disk_size = "40G" } etcd_witness_config = { From 104df8d174f8ce754dcd3beb45b8e72de62109ab Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Tue, 9 Dec 2025 13:15:51 +0100 Subject: [PATCH 13/14] Ajout des disques cloud-init dans la configuration Terraform --- terraform/pve1/main.tf | 6 ++++++ terraform/pve2/main.tf | 6 ++++++ terraform/pve3/main.tf | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/terraform/pve1/main.tf b/terraform/pve1/main.tf index 285e8a8..3700953 100644 --- a/terraform/pve1/main.tf +++ b/terraform/pve1/main.tf @@ -54,6 +54,12 @@ resource "proxmox_vm_qemu" "k3s_server_1" { iothread = true } + disk { + slot = "ide2" + type = "cloudinit" + storage = var.k3s_server_1_storage_pool + } + ipconfig0 = "ip=${var.k3s_server_1_config.ip},gw=${var.k3s_gateway}" cicustom = "user=${var.snippets_storage}:snippets/cloud-init-k3s-server-1.yaml" nameserver = join(" ", var.k3s_dns) diff --git a/terraform/pve2/main.tf b/terraform/pve2/main.tf index c0b4afe..22e973d 100644 --- a/terraform/pve2/main.tf +++ b/terraform/pve2/main.tf @@ -54,6 +54,12 @@ resource "proxmox_vm_qemu" "k3s_server_2" { iothread = true } + disk { + slot = "ide2" + type = "cloudinit" + storage = var.k3s_server_2_storage_pool + } + ipconfig0 = "ip=${var.k3s_server_2_config.ip},gw=${var.k3s_gateway}" cicustom = "user=${var.snippets_storage}:snippets/cloud-init-k3s-server-2.yaml" nameserver = join(" ", var.k3s_dns) diff --git a/terraform/pve3/main.tf b/terraform/pve3/main.tf index a1ab8f5..f9ce1c5 100644 --- a/terraform/pve3/main.tf +++ b/terraform/pve3/main.tf @@ -54,6 +54,12 @@ resource "proxmox_vm_qemu" "etcd_witness" { iothread = true } + disk { + slot = "ide2" + type = "cloudinit" + storage = var.etcd_witness_storage_pool + } + ipconfig0 = "ip=${var.etcd_witness_config.ip},gw=${var.k3s_gateway}" cicustom = "user=${var.snippets_storage}:snippets/cloud-init-etcd-witness.yaml" nameserver = join(" ", var.k3s_dns) From 2d680cec4ef32478db3d0b686668817e6db77cfc Mon Sep 17 00:00:00 2001 From: Tellsanguis Date: Tue, 9 Dec 2025 13:44:57 +0100 Subject: [PATCH 14/14] Ajout snippets cloud-init --- snippets/README.md | 34 ++++++++++++++++++ snippets/cloud-init-etcd-witness.yaml | 50 +++++++++++++++++++++++++++ snippets/cloud-init-k3s-server-1.yaml | 50 +++++++++++++++++++++++++++ snippets/cloud-init-k3s-server-2.yaml | 50 +++++++++++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 snippets/README.md create mode 100644 snippets/cloud-init-etcd-witness.yaml create mode 100644 snippets/cloud-init-k3s-server-1.yaml create mode 100644 snippets/cloud-init-k3s-server-2.yaml diff --git a/snippets/README.md b/snippets/README.md new file mode 100644 index 0000000..251f895 --- /dev/null +++ b/snippets/README.md @@ -0,0 +1,34 @@ +# Cloud-Init Snippets pour Proxmox + +## Avant l'upload + +Remplace les placeholders dans chaque fichier YAML : + +- `YOUR_SSH_PUBLIC_KEY` : Ta clé SSH publique +- `YOUR_FORGEJO_REPO_URL` : URL du dépôt Forgejo (ex: https://forgejo.tellserv.fr/Tellsanguis/Homelab.git) +- `YOUR_FORGEJO_TOKEN` : Token Forgejo +- `YOUR_K3S_TOKEN` : Token K3S cluster + +## Upload via interface Proxmox + +### acemagician (k3s-server-1) +1. Proxmox → acemagician → Datacenter → Storage → local +2. Content → Snippets → Upload +3. Upload `cloud-init-k3s-server-1.yaml` + +### elitedesk (k3s-server-2) +1. Proxmox → elitedesk → Datacenter → Storage → local +2. Content → Snippets → Upload +3. Upload `cloud-init-k3s-server-2.yaml` + +### thinkpad (etcd-witness) +1. Proxmox → thinkpad → Datacenter → Storage → local +2. Content → Snippets → Upload +3. Upload `cloud-init-etcd-witness.yaml` + +## Vérification + +Après upload, les fichiers doivent être présents dans : +- `/var/lib/vz/snippets/cloud-init-k3s-server-1.yaml` (acemagician) +- `/var/lib/vz/snippets/cloud-init-k3s-server-2.yaml` (elitedesk) +- `/var/lib/vz/snippets/cloud-init-etcd-witness.yaml` (thinkpad) diff --git a/snippets/cloud-init-etcd-witness.yaml b/snippets/cloud-init-etcd-witness.yaml new file mode 100644 index 0000000..c7b5ccd --- /dev/null +++ b/snippets/cloud-init-etcd-witness.yaml @@ -0,0 +1,50 @@ +package_upgrade: true +packages: + - ansible + - git + - curl + - wget + - ca-certificates + - gnupg + - lsb-release +users: + - name: ansible + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + ssh_authorized_keys: + - YOUR_SSH_PUBLIC_KEY + groups: sudo +timezone: Europe/Paris +write_files: + - path: /etc/node-role + content: witness + permissions: "0644" + - path: /etc/ansible-pull.conf + content: | + REPO_URL=YOUR_FORGEJO_REPO_URL + FORGEJO_TOKEN=YOUR_FORGEJO_TOKEN + K3S_VERSION=v1.28.5+k3s1 + K3S_TOKEN=YOUR_K3S_TOKEN + permissions: "0600" + - path: /usr/local/bin/ansible-pull-wrapper.sh + content: | + #!/bin/bash + set -e + source /etc/ansible-pull.conf + export K3S_TOKEN + export FORGEJO_TOKEN + export REPO_URL + WORK_DIR="/var/lib/ansible-local" + mkdir -p $WORK_DIR + cd $WORK_DIR + REPO_WITH_AUTH=$(echo $REPO_URL | sed "s|https://|https://git:$FORGEJO_TOKEN@|") + if [ -d ".git" ]; then + git pull origin main 2>&1 | logger -t ansible-pull + else + git clone $REPO_WITH_AUTH . 2>&1 | logger -t ansible-pull + fi + ansible-playbook ansible/site.yml -i localhost, --connection=local -e "k3s_version=$K3S_VERSION" 2>&1 | logger -t ansible-pull + permissions: "0755" +runcmd: + - echo '*/15 * * * * root /usr/local/bin/ansible-pull-wrapper.sh' > /etc/cron.d/ansible-pull + - sleep 60 && /usr/local/bin/ansible-pull-wrapper.sh & diff --git a/snippets/cloud-init-k3s-server-1.yaml b/snippets/cloud-init-k3s-server-1.yaml new file mode 100644 index 0000000..4d55fbf --- /dev/null +++ b/snippets/cloud-init-k3s-server-1.yaml @@ -0,0 +1,50 @@ +package_upgrade: true +packages: + - ansible + - git + - curl + - wget + - ca-certificates + - gnupg + - lsb-release +users: + - name: ansible + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + ssh_authorized_keys: + - YOUR_SSH_PUBLIC_KEY + groups: sudo +timezone: Europe/Paris +write_files: + - path: /etc/node-role + content: server + permissions: "0644" + - path: /etc/ansible-pull.conf + content: | + REPO_URL=YOUR_FORGEJO_REPO_URL + FORGEJO_TOKEN=YOUR_FORGEJO_TOKEN + K3S_VERSION=v1.28.5+k3s1 + K3S_TOKEN=YOUR_K3S_TOKEN + permissions: "0600" + - path: /usr/local/bin/ansible-pull-wrapper.sh + content: | + #!/bin/bash + set -e + source /etc/ansible-pull.conf + export K3S_TOKEN + export FORGEJO_TOKEN + export REPO_URL + WORK_DIR="/var/lib/ansible-local" + mkdir -p $WORK_DIR + cd $WORK_DIR + REPO_WITH_AUTH=$(echo $REPO_URL | sed "s|https://|https://git:$FORGEJO_TOKEN@|") + if [ -d ".git" ]; then + git pull origin main 2>&1 | logger -t ansible-pull + else + git clone $REPO_WITH_AUTH . 2>&1 | logger -t ansible-pull + fi + ansible-playbook ansible/site.yml -i localhost, --connection=local -e "k3s_version=$K3S_VERSION" 2>&1 | logger -t ansible-pull + permissions: "0755" +runcmd: + - echo '*/15 * * * * root /usr/local/bin/ansible-pull-wrapper.sh' > /etc/cron.d/ansible-pull + - sleep 60 && /usr/local/bin/ansible-pull-wrapper.sh & diff --git a/snippets/cloud-init-k3s-server-2.yaml b/snippets/cloud-init-k3s-server-2.yaml new file mode 100644 index 0000000..4d55fbf --- /dev/null +++ b/snippets/cloud-init-k3s-server-2.yaml @@ -0,0 +1,50 @@ +package_upgrade: true +packages: + - ansible + - git + - curl + - wget + - ca-certificates + - gnupg + - lsb-release +users: + - name: ansible + sudo: ALL=(ALL) NOPASSWD:ALL + shell: /bin/bash + ssh_authorized_keys: + - YOUR_SSH_PUBLIC_KEY + groups: sudo +timezone: Europe/Paris +write_files: + - path: /etc/node-role + content: server + permissions: "0644" + - path: /etc/ansible-pull.conf + content: | + REPO_URL=YOUR_FORGEJO_REPO_URL + FORGEJO_TOKEN=YOUR_FORGEJO_TOKEN + K3S_VERSION=v1.28.5+k3s1 + K3S_TOKEN=YOUR_K3S_TOKEN + permissions: "0600" + - path: /usr/local/bin/ansible-pull-wrapper.sh + content: | + #!/bin/bash + set -e + source /etc/ansible-pull.conf + export K3S_TOKEN + export FORGEJO_TOKEN + export REPO_URL + WORK_DIR="/var/lib/ansible-local" + mkdir -p $WORK_DIR + cd $WORK_DIR + REPO_WITH_AUTH=$(echo $REPO_URL | sed "s|https://|https://git:$FORGEJO_TOKEN@|") + if [ -d ".git" ]; then + git pull origin main 2>&1 | logger -t ansible-pull + else + git clone $REPO_WITH_AUTH . 2>&1 | logger -t ansible-pull + fi + ansible-playbook ansible/site.yml -i localhost, --connection=local -e "k3s_version=$K3S_VERSION" 2>&1 | logger -t ansible-pull + permissions: "0755" +runcmd: + - echo '*/15 * * * * root /usr/local/bin/ansible-pull-wrapper.sh' > /etc/cron.d/ansible-pull + - sleep 60 && /usr/local/bin/ansible-pull-wrapper.sh &