Thursday, November 21, 2024

Triển khai máy ảo lên Proxmox bằng Terraform

-

  • Terraform là một công cụ mã hóa cơ sở hạ tầng (Infrastructure as Code – IaC) được phát triển bởi HashiCorp. Nó cho phép bạn xác định và quản lý hạ tầng của mình dưới dạng mã, thay vì phải thực hiện thủ công hoặc sử dụng các công cụ quản lý hạ tầng truyền thống.
  • Proxmox VE (Virtual Environment) là một nền tảng ảo hóa mã nguồn mở dựa trên KVM và lớp quản lý hạ tầng ảo hóa (Virtual Infrastructure Manager – VIM). Nó cung cấp các tính năng quản lý và triển khai máy ảo trên một môi trường ảo hóa.
  • Terraform được sử dụng cho Proxmox VE để tự động hóa quy trình triển khai và quản lý máy ảo trên Proxmox. Terraform cho phép bạn xác định cấu hình Proxmox VE bằng mã, viết trong ngôn ngữ cấu hình của Terraform, và sử dụng các tài nguyên và module được cung cấp bởi nhà cung cấp Terraform cho Proxmox. Điều này giúp đơn giản hóa quy trình triển khai và quản lý hạ tầng Proxmox VE, cho phép việc tái tạo, mở rộng và điều chỉnh hạ tầng trở nên dễ dàng và nhất quán.

Bằng cách sử dụng Terraform cho Proxmox VE, bạn có thể xác định các máy ảo, mạng, ổ đĩa, và các thành phần khác của một hạ tầng ảo hóa Proxmox dưới dạng mã, và sử dụng Terraform để triển khai, cập nhật và quản lý chúng một cách tự động và nhất quán. Điều này giúp giảm thiểu sai sót, tăng tính nhất quán và khả năng tái tạo, và nhanh chóng phản hồi khi thay đổi yêu cầu hạ tầng.

Đầu tiên bạn hãy tạo một thư mục chứa các file cấu hình để triển khai máy ảo trên Proxmox.

mkdir -p ./tf-proxmox

Di chuyển vào thư mục vừa tạo.

cd ./tf-proxmox

Tạo 2 file main.tfvars.tf trong thư mục này.

touch main.tf
touch vars.tf

Ở file main.tf bạn hãy thêm các nội dung sau đây:

  • Khai báo required_providers:
    • Đây là phần khai báo các nhà cung cấp (providers) mà mô-đun Terraform cần sử dụng.
    • Trong ví dụ này, chỉ định rằng mô-đun sẽ sử dụng nhà cung cấp proxmox từ source “Telmate/proxmox” và phiên bản 2.9.14 của nhà cung cấp này.
terraform {
  required_providers {
    proxmox = {
      source = "Telmate/proxmox"
      version = "2.9.14"
    }
  }
}
  • Tạo provider cung cấp cho Terraform.

Đầu tiên bạn hãy vào User -> Add -> điền thông tin Username, tại phần Realm chọn Linux PAM standard authentication và sau đó bấm Add.

Bạn sẽ có username mới như dưới.

Tiếp theo bạn vào API Tokens -> Add -> chọn Username vừa tạo và đặt một tên Token ID (tên này bạn tự đặt), bỏ tích ở Privilege Separation và bấm Add.

Bạn nhận được thông tin TokenID và Secret như dưới, hãy lưu thông tin này lại để lát chúng ta truyền vào Provider trong file kịch bản Terraform.

Bạn sẽ có một API Tokens như dưới.

Cuối cùng bạn vào Permissions -> Add -> User Permission.

Ở đây mình sẽ phân quyền cho người dùng hoanghd vào /storage/ceph-vm với Role là toàn quyền trong storage này.

Sau khi bấm Add bạn sẽ có một Permissions mới như dưới.

  • Khai báo provider:
    • Đây là phần khai báo các thiết lập cho nhà cung cấp proxmox.
    • Địa chỉ URL pm_api_url được sử dụng để truy cập vào API của Proxmox.
    • pm_api_token_id và pm_api_token_secret là thông tin xác thực để đăng nhập vào API của Proxmox bạn hãy điền vào theo thông tin bạn đã lấy được ở bước trên nhé.
    • pm_tls_insecure được đặt là true để bỏ qua việc xác nhận chứng chỉ TLS, nhưng điều này không được khuyến nghị trong môi trường thực tế.
provider "proxmox" {
  pm_api_url = "https://192.168.13.225:8006/api2/json"
  pm_api_token_id = "hoanghd@pam!hoanghd-id"
  pm_api_token_secret = "388f847f-b02f-45fc-a5ff-1e11d9770a92"
  pm_tls_insecure = true
}
  • Khai báo resource proxmox_vm_qemu:
    • Đây là phần khai báo một tài nguyên máy ảo (VM) trên Proxmox.
    • Tham số count được đặt là 1, chỉ định rằng sẽ chỉ tạo một máy ảo.
    • Thuộc tính name là tên máy ảo, trong ví dụ này, nó được đặt theo dạng “test-vm-${count.index + 1}”.
    • Thuộc tính target_node chỉ định nút (node) mục tiêu để tạo máy ảo.
    • Thuộc tính clone chỉ định tên mẫu (template) để sao chép máy ảo từ đó.
    • Các thuộc tính khác như agent, os_type, cores, sockets, cpu, memory, scsihw, bootdisk được cấu hình cho máy ảo.
    • Thuộc tính disk định nghĩa các thuộc tính liên quan đến ổ đĩa của máy ảo.
    • Thuộc tính network định nghĩa các thuộc tính liên quan đến mạng của máy ảo.
    • Lifecycle block được sử dụng để đặt giá trị ignore_changes để bỏ qua các thay đổi của thuộc tính network khi áp dụng (apply) Terraform.
    • Cuối cùng, các thuộc tính ipconfig0 và sshkeys được cấu hình để chỉ định địa chỉ IP và khóa SSH cho máy ảo.
resource "proxmox_vm_qemu" "test_server" {
  count = 1
  name = "test-vm-${count.index + 1}"
  target_node = var.proxmox_host
  clone = var.template_name

  agent = 1
  os_type = "cloud-init"
  cores = 2
  sockets = 1
  cpu = "host"
  memory = 2048
  scsihw = "virtio-scsi-pci"
  bootdisk = "scsi0"

  disk {
    slot = 0
    size = "100G"
    type = "scsi"
    storage = "ceph-vm"
    iothread = 0
  }

  network {
    model = "virtio"
    bridge = "vmbr0"
  }

  lifecycle {
    ignore_changes = [
      network,
    ]
  }

  ipconfig0 = "ip=192.168.13.231${count.index + 1}/23,gw=192.168.12.5"

  sshkeys = <<EOF
  ${var.ssh_key}
  EOF
}

Ở file vars.tf các bạm thêm nội dung dưới vào.

variable "ssh_key" {
  default = "ssh-rsa CBGFB3NzaC1yc2EAAAABIwAAAQEAxwldSynNWYEj36iWSNvsLU821sIW5cpzOWySWlaR8KrREFjNfCYQJWFRfzk+s+wrKSYGifvYxFvGEEsUMA80WEZEKQ1xY6s/lAoD1+Y5cJ5cbohNRYYno1rEUDLqz2qeARUSDyKVRw8LVtU6/01NYcGJECwavNUkzP219OUP8HmYKZXFWWLT9C6M1ftkUYaeI8RSn+cQr0UPDkJ92ERtRvsqQTpewNHSHpC7sS8lLDPR2nhXddUV1Fk8kII6gQAyH3nZ0329IUU7JwoW9RTwiD6aPkmtFQWlJSP56oHLlxr+wkk2pOoxZ5fzxpi7icbej4g9FNDBQ2KLeQWdGhNqpQ=="
}

variable "proxmox_host" {
    default = "pve-node1"
}

variable "template_name" {
    default = "ubuntu-2004-cloudinit-template"
}

Trong đoạn config trên, các biến (variables) được định nghĩa để lưu trữ giá trị có thể thay đổi hoặc được truyền vào từ bên ngoài. Cụ thể:

  • Biến “ssh_key”:
    • Đây là biến để lưu trữ khóa SSH được sử dụng để truy cập vào máy ảo.
    • Giá trị mặc định của biến là khóa SSH đã được cung cấp.
  • Biến “proxmox_host”:
    • Đây là biến để lưu trữ tên nút (node) mục tiêu, nơi máy ảo sẽ được tạo.
    • Giá trị mặc định của biến là “pve-node1”.
  • Biến “template_name”:
    • Đây là biến để lưu trữ tên mẫu (template) sẽ được sao chép để tạo máy ảo.
    • Giá trị mặc định của biến là “ubuntu-2004-cloudinit-template”.

Các biến này cho phép bạn tùy chỉnh giá trị của chúng theo nhu cầu của bạn. Bằng cách định nghĩa giá trị mặc định cho các biến này, bạn có thể thay đổi các giá trị này một cách dễ dàng khi cần thiết.

Sau khi chuẩn bị xong file cấu hình, bạn chạy lệnh terraform init.

  • Lệnh này được sử dụng để khởi tạo môi trường làm việc Terraform.
  • Terraform sẽ tải xuống các nhà cung cấp (providers) cần thiết, cài đặt các plugin và thiết lập các tham số cấu hình.
  • Lệnh này chỉ cần chạy một lần đầu tiên sau khi bạn bắt đầu làm việc với dự án Terraform hoặc khi bạn thay đổi cấu hình môi trường làm việc.
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding telmate/proxmox versions matching "2.9.14"...
- Installing telmate/proxmox v2.9.14...
- Installed telmate/proxmox v2.9.14 (self-signed, key ID A9EBBE091B35AFCE)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Tiếp theo bạn chạy lệnh terraform plan.

  • Lệnh này được sử dụng để tạo ra kế hoạch triển khai (execution plan) dựa trên các tệp cấu hình Terraform của bạn.
  • Terraform sẽ so sánh trạng thái hiện tại của hạ tầng (infrastructure) với cấu hình đã định nghĩa của bạn và hiển thị các thay đổi dự kiến sẽ được thực hiện.
  • Lệnh này cho phép bạn kiểm tra trước các thay đổi mà Terraform sẽ thực hiện trước khi triển khai chúng.
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # proxmox_vm_qemu.test_server[0] will be created
  + resource "proxmox_vm_qemu" "test_server" {
      + additional_wait           = 5
      + agent                     = 1
      + automatic_reboot          = true
      + balloon                   = 0
      + bios                      = "seabios"
      + boot                      = (known after apply)
      + bootdisk                  = "scsi0"
      + clone                     = "ubuntu-2004-cloudinit-template"
      + clone_wait                = 10
      + cores                     = 2
      + cpu                       = "host"
      + default_ipv4_address      = (known after apply)
      + define_connection_info    = true
      + force_create              = false
      + full_clone                = true
      + guest_agent_ready_timeout = 100
      + hotplug                   = "network,disk,usb"
      + id                        = (known after apply)
      + kvm                       = true
      + memory                    = 2048
      + name                      = "test-vm-1"
      + nameserver                = (known after apply)
      + onboot                    = false
      + oncreate                  = true
      + os_type                   = "cloud-init"
      + preprovision              = true
      + reboot_required           = (known after apply)
      + scsihw                    = "virtio-scsi-pci"
      + searchdomain              = (known after apply)
      + sockets                   = 1
      + ssh_host                  = (known after apply)
      + ssh_port                  = (known after apply)
      + sshkeys                   = <<-EOT
            ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxwldSynNWYEj36iWSNvsLU821sIW5cpzOWySWlaR8KrREFjNfCYQJWFRfzk+s+wrKSYGifvYxFvGEEsUMA80WEZEKQ1xY6s/lAoD1+Y5cJ5cbohNRYYno1rEUDLqz2qeARUSDyKVRw3LVtU6/01NYcGJECwavNUkzP216OUP8HmYKZXF
WWLT9C6M1ftkUYaeI8RSn+cQr0UPDkJ92ERtRvsqQTpewNHSHpC7sS8lLDPR2nhXddUV1Fk8kII6gQAyH3nZ0329IUU7JwoW9RTwiD6aPkmtFQWlJSP56oHLlxr+wkk2pOoxZ5fzxpi7icbej4g9FNDBQ2KLeQWdGhNqpQ==
        EOT
      + tablet                    = true
      + target_node               = "pve-node1"
      + unused_disk               = (known after apply)
      + vcpus                     = 0
      + vlan                      = -1
      + vmid                      = (known after apply)

      + disk {
          + backup             = true
          + cache              = "none"
          + file               = (known after apply)
          + format             = (known after apply)
          + iops               = 0
          + iops_max           = 0
          + iops_max_length    = 0
          + iops_rd            = 0
          + iops_rd_max        = 0
          + iops_rd_max_length = 0
          + iops_wr            = 0
          + iops_wr_max        = 0
          + iops_wr_max_length = 0
          + iothread           = 0
      + preprovision              = true
      + reboot_required           = (known after apply)
      + scsihw                    = "virtio-scsi-pci"
      + searchdomain              = (known after apply)
      + sockets                   = 1
      + ssh_host                  = (known after apply)
      + ssh_port                  = (known after apply)
      + sshkeys                   = <<-EOT
            ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxwldSynNWYEj36iWSNvsLU821sIW5cpzOWySWlaR8KrREFjNfCYQJWFRfzk+s+wrKSYGifvYxFvGEEsUMA80WEZEKQ1xY6s/lAoD1+Y5cJ5cbohNRYYno1rEUDLqz2qeARUSDyKVRw3LVtU6/01NYcGJECwavNUkzP216OUP8HmYKZXF
WWLT9C6M1ftkUYaeI8RSn+cQr0UPDkJ92ERtRvsqQTpewNHSHpC7sS8lLDPR2nhXddUV1Fk8kII6gQAyH3nZ0329IUU7JwoW9RTwiD6aPkmtFQWlJSP56oHLlxr+wkk2pOoxZ5fzxpi7icbej4g9FNDBQ2KLeQWdGhNqpQ==
        EOT
      + tablet                    = true
      + target_node               = "pve-node1"
      + unused_disk               = (known after apply)
      + vcpus                     = 0
      + vlan                      = -1
      + vmid                      = (known after apply)

      + disk {
          + backup             = true
          + cache              = "none"
          + file               = (known after apply)
          + format             = (known after apply)
          + iops               = 0
          + iops_max           = 0
          + iops_max_length    = 0
          + iops_rd            = 0
          + iops_rd_max        = 0
          + iops_rd_max_length = 0
          + iops_wr            = 0
          + iops_wr_max        = 0
          + iops_wr_max_length = 0
          + iothread           = 0
          + mbps               = 0
          + mbps_rd            = 0
          + mbps_rd_max        = 0
          + mbps_wr            = 0
          + mbps_wr_max        = 0
          + media              = (known after apply)
          + replicate          = 0
          + size               = "100G"
          + slot               = 0
          + ssd                = 0
          + storage            = "ceph-vm"
          + storage_type       = (known after apply)
          + type               = "scsi"
          + volume             = (known after apply)
        }

      + network {
          + bridge    = "vmbr0"
          + firewall  = false
          + link_down = false
          + macaddr   = (known after apply)
          + model     = "virtio"
          + queues    = (known after apply)
          + rate      = (known after apply)
          + tag       = -1
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

Và cuối cùng bạn hãy chạy lệnh terraform apply --auto-approve để triển khai máy ảo này lên Proxmox.

  • Lệnh này được sử dụng để triển khai cấu hình Terraform và tạo ra các tài nguyên hạ tầng dựa trên tệp cấu hình.
  • Terraform sẽ thực hiện các thay đổi cần thiết để đưa hạ tầng từ trạng thái hiện tại đến trạng thái đã định nghĩa trong tệp cấu hình.
  • Tùy chọn --auto-approve được sử dụng để tự động chấp nhận việc triển khai mà không yêu cầu xác nhận từ người dùng.
  • Lệnh này sẽ tạo và cập nhật các tài nguyên một cách tự động, đảm bảo rằng hạ tầng đang chạy đúng theo cấu hình đã định nghĩa.
terraform apply --auto-approve

Lưu ý: Trước khi chạy terraform apply, hãy chắc chắn rằng bạn đã xem xét và hiểu rõ kế hoạch triển khai từ terraform plan. Terraform sẽ thay đổi trạng thái của hạ tầng một cách tự động và không thể hoàn tác nếu không được quản lý cẩn thận.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories