SiamCafe.net Blog
Technology

Proxmox VE Cluster GitOps Workflow

proxmox ve cluster gitops workflow
Proxmox VE Cluster GitOps Workflow | SiamCafe Blog
2025-08-29· อ. บอม — SiamCafe.net· 11,770 คำ

Proxmox VE GitOps

Proxmox VE Cluster GitOps Terraform Ansible CI/CD KVM LXC High Availability Ceph Storage Backup PBS Infrastructure as Code Production

ComponentToolPurposeGitOps Role
VM ProvisioningTerraformสร้าง VM LXC จาก CodeDeclarative state
ConfigurationAnsibleติดตั้ง Software ตั้งค่าIdempotent config
CI/CDGitHub ActionsPlan Apply อัตโนมัติAutomated workflow
StateTerraform Stateเก็บ State ปัจจุบันSource of truth
Version ControlGitTrack ทุกการเปลี่ยนแปลงAudit trail
BackupPBSBackup VM LXCDR strategy

Terraform Proxmox

# === Terraform Proxmox Provider ===

# terraform {
#   required_providers {
#     proxmox = {
#       source  = "telmate/proxmox"
#       version = "3.0.1-rc1"
#     }
#   }
#   backend "s3" {
#     bucket = "terraform-state"
#     key    = "proxmox/terraform.tfstate"
#     region = "ap-southeast-1"
#   }
# }
#
# provider "proxmox" {
#   pm_api_url      = "https://pve1.local:8006/api2/json"
#   pm_user         = "terraform@pam"
#   pm_password     = var.proxmox_password
#   pm_tls_insecure = true
# }
#
# resource "proxmox_vm_qemu" "web_server" {
#   count       = 3
#   name        = "web-"
#   target_node = "pve"
#   clone       = "ubuntu-22.04-template"
#
#   cores   = 4
#   memory  = 8192
#   balloon = 4096
#   scsihw  = "virtio-scsi-single"
#
#   disk {
#     storage = "ceph-pool"
#     size    = "50G"
#     type    = "scsi"
#     ssd     = 1
#   }
#
#   network {
#     model  = "virtio"
#     bridge = "vmbr0"
#     tag    = 100
#   }
#
#   ipconfig0 = "ip=10.0.1./24, gw=10.0.1.1"
#   sshkeys   = file("~/.ssh/id_rsa.pub")
#
#   lifecycle {
#     ignore_changes = [network]
#   }
# }
#
# resource "proxmox_lxc" "db_server" {
#   hostname    = "db-1"
#   target_node = "pve1"
#   ostemplate  = "local:vztmpl/ubuntu-22.04-standard.tar.zst"
#   cores       = 4
#   memory      = 4096
#   swap        = 1024
#   unprivileged = true
#
#   rootfs {
#     storage = "ceph-pool"
#     size    = "30G"
#   }
#
#   network {
#     name   = "eth0"
#     bridge = "vmbr0"
#     ip     = "10.0.1.50/24"
#     gw     = "10.0.1.1"
#   }
# }

from dataclasses import dataclass

@dataclass
class VMSpec:
    name: str
    role: str
    cores: int
    ram_gb: int
    disk_gb: int
    node: str
    ha: bool

vms = [
    VMSpec("web-1", "Web Server", 4, 8, 50, "pve1", True),
    VMSpec("web-2", "Web Server", 4, 8, 50, "pve2", True),
    VMSpec("web-3", "Web Server", 4, 8, 50, "pve3", True),
    VMSpec("db-1", "PostgreSQL Primary", 8, 32, 200, "pve1", True),
    VMSpec("db-2", "PostgreSQL Replica", 8, 32, 200, "pve2", True),
    VMSpec("monitor-1", "Prometheus + Grafana", 4, 8, 100, "pve3", False),
    VMSpec("backup-1", "PBS Server", 4, 16, 500, "pve3", False),
]

print("=== Infrastructure VMs ===")
for v in vms:
    print(f"  [{v.name}] Role: {v.role} | Node: {v.node}")
    print(f"    CPU: {v.cores} cores | RAM: {v.ram_gb}GB | Disk: {v.disk_gb}GB | HA: {v.ha}")

Ansible Configuration

# === Ansible Playbooks ===

# inventory/hosts.yml
# all:
#   children:
#     web_servers:
#       hosts:
#         web-1: { ansible_host: 10.0.1.10 }
#         web-2: { ansible_host: 10.0.1.11 }
#         web-3: { ansible_host: 10.0.1.12 }
#     db_servers:
#       hosts:
#         db-1: { ansible_host: 10.0.1.50 }
#         db-2: { ansible_host: 10.0.1.51 }

# playbooks/web-server.yml
# - hosts: web_servers
#   become: yes
#   roles:
#     - common
#     - nginx
#     - node-exporter
#   tasks:
#     - name: Install packages
#       apt:
#         name: [nginx, certbot, python3-certbot-nginx]
#         state: present
#         update_cache: yes
#
#     - name: Deploy nginx config
#       template:
#         src: nginx.conf.j2
#         dest: /etc/nginx/sites-available/default
#       notify: restart nginx
#
#     - name: Enable firewall rules
#       ufw:
#         rule: allow
#         port: "{{ item }}"
#       loop: ["80", "443", "9100"]

# Proxmox Cluster Commands
# pvecm create my-cluster              # Create cluster
# pvecm add 10.0.1.2                   # Add node
# pvecm status                         # Check cluster status
# pvecm expected 1                     # Set expected votes (emergency)
# ha-manager set vm:100 --state started # Enable HA for VM
# ha-manager groupadd ha-group --nodes pve1, pve2, pve3

@dataclass
class ClusterCommand:
    command: str
    purpose: str
    when: str

commands = [
    ClusterCommand("pvecm create cluster-name", "สร้าง Cluster ใหม่", "ครั้งแรก Node แรก"),
    ClusterCommand("pvecm add 10.0.1.1", "เพิ่ม Node เข้า Cluster", "Node ใหม่ทุกตัว"),
    ClusterCommand("pvecm status", "ดู Cluster Status", "ตรวจสอบปกติ"),
    ClusterCommand("pvecm nodes", "ดู Nodes ทั้งหมด", "ตรวจสอบ"),
    ClusterCommand("ha-manager set vm:100 --state started", "เปิด HA สำหรับ VM", "VM สำคัญ"),
    ClusterCommand("ceph status", "ดู Ceph Storage Status", "ตรวจสอบ Storage"),
    ClusterCommand("qm migrate 100 pve2", "ย้าย VM ไป Node อื่น", "Maintenance"),
    ClusterCommand("vzdump 100 --storage pbs", "Backup VM ไป PBS", "Backup"),
]

print("\n=== Proxmox Commands ===")
for c in commands:
    print(f"  [{c.command}]")
    print(f"    Purpose: {c.purpose} | When: {c.when}")

CI/CD Pipeline

# === GitHub Actions GitOps Pipeline ===

# .github/workflows/proxmox-gitops.yml
# name: Proxmox GitOps
# on:
#   pull_request:
#     paths: ['terraform/**', 'ansible/**']
#   push:
#     branches: [main]
#     paths: ['terraform/**', 'ansible/**']
#
# jobs:
#   terraform-plan:
#     if: github.event_name == 'pull_request'
#     runs-on: self-hosted
#     steps:
#       - uses: actions/checkout@v4
#       - uses: hashicorp/setup-terraform@v3
#       - run: terraform init
#         working-directory: terraform/
#       - run: terraform plan -out=plan.tfplan
#         working-directory: terraform/
#       - uses: actions/github-script@v7
#         with:
#           script: |
#             const plan = require('fs').readFileSync('terraform/plan.txt', 'utf8');
#             github.rest.issues.createComment({
#               owner: context.repo.owner,
#               repo: context.repo.repo,
#               issue_number: context.issue.number,
#               body: '```\n' + plan + '\n```'
#             });
#
#   terraform-apply:
#     if: github.ref == 'refs/heads/main' && github.event_name == 'push'
#     runs-on: self-hosted
#     steps:
#       - uses: actions/checkout@v4
#       - run: terraform init && terraform apply -auto-approve
#         working-directory: terraform/
#
#   ansible-configure:
#     needs: terraform-apply
#     runs-on: self-hosted
#     steps:
#       - uses: actions/checkout@v4
#       - run: ansible-playbook -i inventory/hosts.yml playbooks/site.yml

@dataclass
class GitOpsStep:
    step: str
    trigger: str
    action: str
    safety: str

steps = [
    GitOpsStep("1. Developer creates PR", "Code push", "terraform plan runs automatically",
        "Plan output posted as PR comment"),
    GitOpsStep("2. Team reviews PR", "PR created", "Review Terraform plan + Ansible changes",
        "Approval required from 2 reviewers"),
    GitOpsStep("3. Merge to main", "PR approved", "terraform apply runs automatically",
        "State locked during apply"),
    GitOpsStep("4. Ansible configure", "After Terraform", "ansible-playbook runs on new VMs",
        "Idempotent — safe to re-run"),
    GitOpsStep("5. Health check", "After Ansible", "Verify VMs running + services healthy",
        "Auto-rollback if health check fails"),
]

print("GitOps Workflow:")
for s in steps:
    print(f"  [{s.step}]")
    print(f"    Trigger: {s.trigger} | Action: {s.action}")
    print(f"    Safety: {s.safety}")

เคล็ดลับ

Proxmox VE คืออะไร

Open Source Virtualization KVM LXC Web UI Cluster 32 Nodes HA Ceph Storage Backup ZFS REST API ฟรี Enterprise Subscription

GitOps สำหรับ Proxmox ทำอย่างไร

Git Repository Terraform Proxmox Provider VM LXC Code Ansible Configuration CI/CD GitHub Actions PR Review Apply State Rollback

ตั้ง Cluster อย่างไร

3 Nodes Quorum pvecm create add Corosync Ceph Shared Storage HA Group Failover VM ย้ายอัตโนมัติ ทดสอบ

Backup Strategy ทำอย่างไร

PBS Proxmox Backup Server อัตโนมัติทุกวัน Incremental Deduplication GFS 7 วัน 4 สัปดาห์ 3 เดือน Restore ทดสอบทุกเดือน Offsite Sync

สรุป

Proxmox VE Cluster GitOps Terraform Ansible CI/CD KVM LXC HA Ceph Storage PBS Backup Infrastructure as Code Production Operations

📖 บทความที่เกี่ยวข้อง

Proxmox VE Cluster Chaos Engineeringอ่านบทความ → Proxmox VE Cluster Compliance Automationอ่านบทความ → Apache Arrow GitOps Workflowอ่านบทความ → Proxmox VE Cluster Database Migrationอ่านบทความ → Proxmox VE Cluster อ่านบทความ →

📚 ดูบทความทั้งหมด →