Friday, November 1, 2024

[Terraform] Hướng dẫn tạo virtual machine trên vCenter bằng Terraform

-

Bài trước mình đã giới thiệu cho các bạn Terraform là gì, ở bài viết này mình sẽ hướng dẫn các bạn tạo một hoặc nhiều virtual machine bằng Terraform trên vCenter nhé.

I. CHUẨN BỊ FILE CẤU HÌNH.

1. Đầu tiên các bạn tạo thư mục để chứa các file cấu hình Terraform.

mkdir -p /root/terraform
cd /root/terraform

2. Tạo file /root/terraform/main.tf với nội dung sau.

Đầu tiên chúng ta tạo 1 block có format như dưới, ở block này chúng ta nhận khai báo thông tin provider của vCenter, ví dụ như user, password, địa chỉ server.

provider "vsphere" {
  user           = var.vsphere_env.user
  password       = var.vsphere_env.password
  vsphere_server = var.vsphere_env.server
  allow_unverified_ssl = true
}

Ở block vsphere_virtual_machine ta khai báo thông tin các resource (cpu, ram, disk, …). Mỗi resource chúng ta cũng khai báo theo dạng block, tạm thời gọi các block này là block con.

resource vsphere_virtual_machine "allvms" {
  for_each = var.vms
 
  resource_pool_id = data.vsphere_compute_cluster.this[each.key].resource_pool_id
  datastore_id     = data.vsphere_datastore.this[each.key].id
 
  name = each.value.vmname
  num_cpus = each.value.vCPU
  memory   = each.value.vMEM
   
  guest_id = data.vsphere_virtual_machine.template[each.key].guest_id
  scsi_type = data.vsphere_virtual_machine.template[each.key].scsi_type
}

– Các block con sẽ có dạng như sau:

+ VÍ dụ về 1 block ổ đĩa cd-rom

cdrom {
  client_device = true
}

+ VÍ dụ về 1 block network

network_interface {
  network_id   = data.vsphere_network.this[each.key].id
  adapter_type = data.vsphere_virtual_machine.template[each.key].network_interface_types[0]
}

Ở phần này mình sẽ bổ sung thêm dữ liệu cấu hình bổ sung cho máy ảo. Có thể được sử dụng để cung cấp các thông số nâng cao không bình thường trong cấu hình. Phần này các bạn có thể có hoặc không có tùy theo nhu cầu nhé.

extra_config = {
  "guestinfo.metadata"          = base64encode(data.template_file.metadataconfig[each.key].rendered)
  "guestinfo.metadata.encoding" = "base64"
  "guestinfo.userdata"          = base64encode(data.template_file.kickstartconfig[each.key].rendered)
  "guestinfo.userdata.encoding" = "base64"
}

Ở block clone bắt buộc phải có để nó tạo ra các file chứa thông tin máy ảo sẽ được tạo, ví dụ như uuid chẳng hạn.

clone {
  template_uuid = data.vsphere_virtual_machine.template[each.key].id
}

Ở block connection mình sử dụng để ssh vào máy ảo khi nó đã được tạo bằng cách sử dụng sshkey

connection {
  host     = each.value.ip
  type     = "ssh"
  user     = "root"
  private_key = "${file("./common/id_rsa")}"
  timeout     = "10m"
} 

Phần này mình sẽ copy file sshconfig.sh vào máy ảo đã được tạo và tiến hành chạy nó với mục đích để config một số thông tin liên quan đến cấu hình ssh.

Nội dung file sshconfig.sh các bạn xem ở phía dưới nhé.

provisioner "file" {
  source      = "./scripts/sshconfig.sh"
  destination = "/usr/local/bin/sshconfig"
}

Sau khi remote được vào server, mình sẽ tiến hành chạy một số command để kết thúc quá trình tạo máy ảo ví dụ như update hệ thống hoặc chạy sshconfig.sh mà trước đó mình đã copy vào server.

provisioner "remote-exec" {
  inline = [
    "sudo chmod -R 777 /usr/local/bin/sshconfig",
    "sudo sshconfig",
    "sudo apt update -y",
    "sudo apt upgrade -y"
  ]
}

3. Tổng kết lại thì file main.tf đầy đủ của mình sẽ là như vậy.

provider "vsphere" {
  user           = var.vsphere_env.user
  password       = var.vsphere_env.password
  vsphere_server = var.vsphere_env.server
  allow_unverified_ssl = true
}

resource vsphere_virtual_machine "allvms" {
  for_each = var.vms

  resource_pool_id = data.vsphere_compute_cluster.this[each.key].resource_pool_id
  datastore_id     = data.vsphere_datastore.this[each.key].id

  name = each.value.vmname
  num_cpus = each.value.vCPU
  memory   = each.value.vMEM
  
  guest_id = data.vsphere_virtual_machine.template[each.key].guest_id
  scsi_type = data.vsphere_virtual_machine.template[each.key].scsi_type

  cdrom {
    client_device = true
  }

  network_interface {
    network_id   = data.vsphere_network.this[each.key].id
    adapter_type = data.vsphere_virtual_machine.template[each.key].network_interface_types[0]
  }
  wait_for_guest_net_timeout = 0

  disk {
    label            = "disk0"
    size             = data.vsphere_virtual_machine.template[each.key].disks.0.size
    eagerly_scrub    = data.vsphere_virtual_machine.template[each.key].disks.0.eagerly_scrub
    thin_provisioned = data.vsphere_virtual_machine.template[each.key].disks.0.thin_provisioned
  }

  clone {
    template_uuid = data.vsphere_virtual_machine.template[each.key].id
  }

  extra_config = {
    "guestinfo.metadata"          = base64encode(data.template_file.metadataconfig[each.key].rendered)
    "guestinfo.metadata.encoding" = "base64"
    "guestinfo.userdata"          = base64encode(data.template_file.kickstartconfig[each.key].rendered)
    "guestinfo.userdata.encoding" = "base64"
  }

  connection {
    host     = each.value.ip
    type     = "ssh"
    user     = "root"
    private_key = "${file("./common/id_rsa")}"
    timeout     = "10m"
  } 

  provisioner "file" {
    source      = "./scripts/sshconfig.sh"
    destination = "/usr/local/bin/sshconfig"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo chmod -R 777 /usr/local/bin/sshconfig",
      "sudo sshconfig",
      "sudo apt update -y",
      "sudo apt upgrade -y"
    ]
  }
}

3. Tạo file /root/terraform/variables.tf

Ở file variables.tf chúng ta cần chú ý các giá trị server, user, password, gw và dns. Các bạn nhớ define lại cho đúng với thông tin cụm vCenter của bạn.

Ở phần này mình khai báo các biến liên quan đến thông tin remote vào vCenter, mình sẽ để mặc định thông tin server có thông tin như dưới, ý nghĩa của nó là nếu chúng ta không khai báo thông tin remote vào server ở trong file terraform.tfvars thì terraform sẽ lấy thông tin này để remote vào server.

variable "vsphere_env" {
    type = object({
        server = string
        user = string
        password = string
    })
    default = {
        server = "vcenter.hoanghd.com"
        user = "administrator@hoanghd.com"
        password = "Hoanghd164"
    }
}

Ở phần này mình define thông tin network, cụ thể là ip gateway và thông tin dns server.

variable "vm_env" {
    type = object({
        gw = string
        dns = string
    })
    default = {
        gw = "192.168.12.5"
        dns = "8.8.8.8"
    }
}

Phần cuối trong file này mình define các biến liên quan đến máy ảo, ví dụ như ram, cpu, hostname,…

variable "vms" {
    type = map(object({
        vCPU = number
        vMEM = number
        vmname = string
        datastore = string
        network = string
        user = string
        password = string
        template = string
        cluster = string
        datacenter = string
        hostname = string
        domain_name = string
        ip = string
        netmask = string
    }))
}

Như vậy file variables.tf đầy đủ của mình sẽ có nội dung như dưới

#cloud variables
variable "vsphere_env" {
    type = object({
        server = string
        user = string
        password = string
    })
    default = {
        server = "vcenter.hoanghd.com"
        user = "administrator@hoanghd.com"
        password = "Hoanghd164"
    }
}

variable "vm_env" {
    type = object({
        gw = string
        dns = string
    })
    default = {
        gw = "192.168.12.5"
        dns = "8.8.8.8"
    }
}

variable "vms" {
    type = map(object({
        vCPU = number
        vMEM = number
        vmname = string
        datastore = string
        network = string
        user = string
        password = string
        template = string
        cluster = string
        datacenter = string
        hostname = string
        domain_name = string
        ip = string
        netmask = string
    }))
}

4. Tạo file /root/terraform/vsphere_data.tf

Ở file này mình define các các thông tin đã được khai báo ở phần tiếp theo, phần này các dữ liệu đã được list ra thành các phần tử để xử lý lần lượt.

Ví dụ có 1 list máy ảo a,b,c nào đó, phần này nó sẽ tách ra và xử lý từng máy ảo (máy ảo a rồi đến máy ảo b,…). Biến for_each = var.vms dùng để rã các phần tử trong mảng để xử lý. Vì bài viết khá dài nên mình không đi sâu vào từng block, bạn nào thắc mắc có thể comment cho mình.

data vsphere_datacenter "this" {
  for_each = var.vms
  name = each.value.datacenter
}

data vsphere_compute_cluster "this" {
  for_each = var.vms
  name          = each.value.cluster
  datacenter_id = data.vsphere_datacenter.this[each.key].id
}

data vsphere_datastore "this" {
  for_each = var.vms
  name          = each.value.datastore
  datacenter_id = data.vsphere_datacenter.this[each.key].id
}

data vsphere_network "this" {
  for_each = var.vms
  name          = each.value.network
  datacenter_id = data.vsphere_datacenter.this[each.key].id
}

data vsphere_virtual_machine "template" {
  for_each = var.vms
  name          = each.value.template
  datacenter_id = data.vsphere_datacenter.this[each.key].id
}

data template_file "metadataconfig" {
  for_each = var.vms
  template = file("${path.module}/common/metadata.yaml")
  vars = {
    ip = "${each.value.ip}"
    netmask = "${each.value.netmask}"
    hostname = "${each.value.hostname}"
    instance_id = "${each.value.vmname}"
    gw = "${var.vm_env.gw}"
    dns = "${var.vm_env.dns}"
  }
}

data template_file "userdataconfig" {
  for_each = var.vms
  template = file("${path.module}/nodes/${each.value.vmname}/cloudinit/userdata.yaml")
  vars = {
    ip = "${each.value.ip}"
    hostname = "${each.value.hostname}"
    domain_name = "${each.value.domain_name}"
    user = "${each.value.user}"
    password = "${each.value.password}"
  }
}

data template_file "kickstartconfig" {
  for_each = var.vms
  template = file("${path.module}/common/kickstart.yaml")
  vars = {
    user = "${each.value.user}"
    password = "${each.value.password}"
    hostname = "${each.value.hostname}"
    domain_name = "${each.value.domain_name}"
  }
}

5. Tạo file khai báo thông tin cấu hình virtual machine /root/terraform/terraform.tfvars

Ở phần này nhìn vô là đủ hiểu rồi, chỉ là khai báo thông tin máy ảo thôi. Chú ý phần datastore, datacenter, cluster, network, template bạn cần khai báo chính xác với cụm vCenter của mình nhé.

vsphere_env = {
    user     = "administrator@hoanghd.com"
    password = "Hoanghd164"
    server   = "vcenter.hoanghd.com"
}
 
vms = {
    vm = { 
        vCPU = 2
        vMEM = 4096
        vmname = "tf-vm"
        datastore = "ssd-1tb"
        datacenter = "Datacenter"
        network = "VM Network"
        cluster = "cluster1"
        template = "bionic-server-cloudimg-amd64"
        ip = "192.168.13.247"
        netmask = "23" 
        hostname = "vm"
        domain_name = "vm.local"
        user = "hoanghd"
        password = "Hoanghd164"
    }
}

5. Tạo thư mục common để lưu các file sử dụng chung hoặc các file chứa các trường sẽ sử dụng đi sử dụng lại nhiều lần chúng ta sẽ cho hết vào đây.

mkdir -p /root/terraform/common
cd /root/terraform/common

6. Tạo file chứa thông tin sshkey

  • Public key
cat > /root/terraform/common/authorized_keys << OEF
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5jYRFel9+12q/xSSBf49Y2YkZ62MFzzcLr1D9QsnZ9w5jK+5e03sQA9pPKwJnCnbuEDGH1J0xZjQ3cZ03QQrLJ93lFSlR2vAcV5mXQttaRzaKKF8R6mlPXbwoQHysBH/03W72sBZ2WOLWzmYM4IIgoY/wJQodXmNTw96jkn8X+8cHodx55m1K82tWBhGdMc3OkiS98qyJR4nsYRq+3lAbd/aUP8v7N4hSP7zjhrgTaO2jOpnbDJjXYuK8WyT/OenQtbzPsdJcomPEbDN3vtd8Hme9GZ0fqS2RrmhpSzydShbGA+ytW5h82wrXAKQWIaiiS6zLihsLd4nAFjINYbxB
OEF
  • Private key
cat > /root/terraform/common/id_rsa << OEF
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuY2ERXpfftdqv8UkgX+PWNmJGetjBc83C69Q/ULJ2fcOYyvu
XtN7EAPaTysCZwp27hAxh9SdMWY0N3GdN0EKyyfd5RUpUdrwHFeZl0LbWkc2iihf
EeppT128KEB8rAR/9N1u9rAWdlji1s5mDOCCIKGP8CUKHV5jU8Peo5J/F/vHB6Hc
eeZtSvNrVgYRnTHNzpIkvfKsiUeJ7GEavt5QG3f2lD/L+zeIUj+844a4E2jtozqZ
2wyY12LivFsk/znp0LW8z7HSXKJjxGwzd77XfB5nvRmdH6ktka5oaUs8nUoWxgPs
rVuYfNsK1wCkFiGookusy4obC3eJwBYyDWG8QQIDAQABAoIBAEH4q8+cC7noUz7t
k+Yq+UdoyJMbmrBlFTglVBFHnsbNTSM7alvyqu1twT+mlgsWsGRCA6o8kMsQgH45
+eC8Ul8axIz/chp1Uitxhd0+2wiFC0IhynNvOZQLSquxCeKLEwd3d01kHAhl3/jp
l2T6qal6Z9fFA4yfk4cju9PCcUeQFQjIE0kN4zpeIwOU7nc4ZDHKPvCjtEMDgbix
XVYyAMivp9G/hi/ltgjN67xplv1RPWiFcLxScyepy/UQGnq0On5EfWe2MrEs9uRB
7ug5iY3zryBhrFQDdy/t4oB+BaeVkPu37pv2WK8mDNjpS43q3B9ob54TqRSwHF4M
8gwe/CUCgYEA4W57jh84j1sskVv6L/3opCGGVM1AFfqs9MVBSg54iIwxoMXcjERC
RARFYiS3TEKn4lPpILp+DBFdvG3n1FNxDufihfBQvVfIx+JAJT7/28/4URlDUmTm
NzjtfVDkGtRWbVI0jT8mkTF8q1PjxxgTuuVP75uCTtrIVQ34AmCp/KsCgYEA0raz
2Ky8kGEIvsbh1buk14QKA2+Y7KP8hUORWdccXe/5dL18h6aRLd07wIh0p+94YagU
whH26vjKO32BcCDAb+p+xkd1zGo/56fvC3v37elrMZFLNw5ObLZp/LmJ0LJh/qD3
U9+qsw3mt64zaep17Ymah2FeU6baz67GR+vm0sMCgYEAzhU6ToqsIiGvdJMo/Iaa
DrG3I/8e/vjS9FD/hrwD5JCFLfyzymb8TUG6TCZUixrEb1tWW90hLdcSYhf3P1uo
l3/Uza0LooyFuHVVPreBH2nYEAuQR9qFuyYHtfAlF4HWIMpt0FJS55jd56IhMPkJ
0Gmh0eHQFlZbnaXPfBzySVECgYBdvR+m/blpNXGxhUKEVdTQd5II00WhyJYXJubr
o7Gf7Jj6IS3cHvKpB6mETnAvIW5Za2/IojtJbuJwsrW5jyhs4VICnVm/VWkWgnPq
lPzH3zZrt6pRVND4tfHSlyvDJwhHQY6lxnPm8gE4p4uBy+cohDW1klBnQGxJRgQ5
jK2EBwKBgHZnF7PgM8V7ax1csPvkGvZ3QvmVPxgho9Wd8dD2M8+Qz7bh7wcbDA/L
2zGORXArJb+S9qykU+xDsOxkzTmJ29m2ijNMdB6yruueLbjpNI7hDEVs2EyIVzJc
1pXIGd1UWFG+MgmU/e1wkJGlNXN25aiJPPjnXGb+46+YuOp1nqrs
-----END RSA PRIVATE KEY-----
OEF

Phân quyền cho public key và private key

chmod -R 600 ./authorized_keys
chmod -R 600 ./id_rsa

7. Tạo file /root/terraform/common/kickstart.yaml để cấu hình các thông tin cơ bản như hostname, username, password, sshkey,….

#cloud-config
hostname: ${hostname}
fqdn: ${domain_name}
manage_etc_hosts: true
users:
  - name: root
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: users, admin, sudo
    home: /home/root
    shell: /bin/bash
    lock_passwd: false
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5jYRFel9+12q/xSSBf49Y2YkZ62MFzzcLr1D9QsnZ9w5jK+5e03sQA9pPKwJnCnbuEDGH1J0xZjQ3cZ03QQrLJ93lFSlR2vAcV5mXQttaRzaKKF8R6mlPXbwoQHysBH/03W72sBZ2WOLWzmYM4IIgoY/wJQodXmNTw96jkn8X+8cHodx55m1K82tWBhGdMc3OkiS98qyJR4nsYRq+3lAbd/aUP8v7N4hSP7zjhrgTaO2jOpnbDJjXYuK8WyT/OenQtbzPsdJcomPEbDN3vtd8Hme9GZ0fqS2RrmhpSzydShbGA+ytW5h82wrXAKQWIaiiS6zLihsLd4nAFjINYbxB
  
  - name: ${user} 
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: users, admin, sudo
    home: /home/${user}
    shell: /bin/bash
    lock_passwd: false

ssh_pwauth: true
disable_root: false
chpasswd:
  list: |
    "root":"Hoanghd164"
    ${user}:${password}
  expire: False

bootcmd:
  - sudo touch /etc/cloud/cloud-init.disabled

8. Tạo file cấu hình network file /root/terraform/common/metadata.yaml

#cloud-config
local-hostname: ${hostname}
instance-id: ${instance_id}
network:
  version: 2
  ethernets:
    ens192:
      dhcp4: false
      addresses:
        - ${ip}/${netmask}
      gateway4: ${gw}
      nameservers:
        addresses:
          - ${dns}

9. Tạo file config cấu hình sshkey cho virtual machine khi nó đã được tạo, bằng cách tạo thư mục script trong thư mục terraform và chạy đoạn code dưới đây

mkdir -p /root/terraform/scripts/
cat > /root/terraform/scripts/sshconfig.sh << OEF
#!/bin/bash
sudo sed -i "s|#PermitRootLogin.*|PermitRootLogin yes|" /etc/ssh/sshd_config
sudo sed -i "s|#PasswordAuthentication.*|PasswordAuthentication yes|" /etc/ssh/sshd_config
sudo sed -i "s|#   PasswordAuthentication.*|PasswordAuthentication yes|" /etc/ssh/ssh_config
sudo service ssh restart || sudo systemctl restart sshd
sudo echo 'root:Hoanghd164' | chpasswd
OEF

11. Tạo file /root/terraform/nodes/tf-vm/cloudinit/userdata.yaml để thực hiện 1 số cài đặt nào đó khi khởi động virtual machine lần đầu tiên ví dụ như update hệ thống hoặc config ssh.

mkdir -p /root/terraform/nodes/tf-vm/cloudinit
cat > /root/terraform/nodes/tf-vm/cloudinit/userdata.yaml << OEF
#cloud-config 
packages:
  - sudo chmod -R 777 /usr/local/bin/sshconfig
  - sudo sshconfig
  - sudo apt update -y
  - sudo apt upgrade -y
runcmd:
  - mkdir -p /mnt/sharedfolder
OEF

10. Hãy kiểm tra lại cấu trúc của các file theo cây thư mục như ở dưới.

.
├── common
│   ├── authorized_keys
│   ├── id_rsa
│   ├── kickstart.yaml
│   └── metadata.yaml
├── main.tf
├── nodes
│   └── vm
│       └── cloudinit
│           └── userdata.yaml
├── scripts
│   └── sshconfig.sh
├── variables.tf
└── vsphere_data.tf

5 directories, 9 files

Đến đây chúng ta đã hoàn thành việc khai báo các file cấu hình, chúng ta tiếp tục sang phần sau để tiếp tục phần tạo các virtual machine nhé.

II. KHỞI TẠO VM BẰNG TERRAFORM

1. Terraform init

Lệnh terraform init khởi tạo một thư mục làm việc có chứa các file cấu hình Terraform. Đây là lệnh đầu tiên sẽ được chạy sau khi viết cấu hình Terraform.

root@terraform:~/terraform# terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/vsphere from the dependency lock file
- Reusing previous version of hashicorp/template from the dependency lock file
- Using previously-installed hashicorp/vsphere v2.2.0
- Using previously-installed hashicorp/template v2.2.0

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.

2. Terraform plan

Bước tiếp theo sử dụng command terraform plan để dọc trạng thái hiện tại đảm bảo rằng trạng thái Terraform được cập nhật, so sánh cấu hình hiện tại với trạng thái trước đó và đề xuất các hành động thay đổi, nếu được áp dụng, sẽ làm cho các đối tượng từ xa phù hợp với cấu hình.

root@terraform:~/terraform# terraform plan
data.template_file.metadataconfig["vm"]: Reading...
data.template_file.kickstartconfig["vm"]: Reading...
data.template_file.userdataconfig["vm"]: Reading...
data.template_file.metadataconfig["vm"]: Read complete after 0s [id=5f7bc09c9df02dd7fcd8dfc178261cc0e489a4d91c4bb5ea6c123f6ad2d50ce6]
data.template_file.kickstartconfig["vm"]: Read complete after 0s [id=9b42b1e407f8332a794b54072c83bc9d9bba41d602ae393a2f4f46207c32036e]
data.template_file.userdataconfig["vm"]: Read complete after 0s [id=128e2de56fad81c251c49c49eb07a0d653aed453c64387ad6926039e00fb7f75]
data.vsphere_datacenter.this["vm"]: Reading...
data.vsphere_datacenter.this["vm"]: Read complete after 0s [id=datacenter-2]
data.vsphere_compute_cluster.this["vm"]: Reading...
data.vsphere_datastore.this["vm"]: Reading...
data.vsphere_network.this["vm"]: Reading...
data.vsphere_virtual_machine.template["vm"]: Reading...
data.vsphere_network.this["vm"]: Read complete after 0s [id=network-12]
data.vsphere_datastore.this["vm"]: Read complete after 0s [id=datastore-60]
data.vsphere_compute_cluster.this["vm"]: Read complete after 0s [id=domain-c7]
data.vsphere_virtual_machine.template["vm"]: Read complete after 0s [id=4212a79e-568f-8a7e-925f-2d68e7a90040]

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:

  # vsphere_virtual_machine.allvms["vm"] will be created
  + resource "vsphere_virtual_machine" "allvms" {
      + annotation                              = (known after apply)
      + boot_retry_delay                        = 10000
      + change_version                          = (known after apply)
      + cpu_limit                               = -1
      + cpu_share_count                         = (known after apply)
      + cpu_share_level                         = "normal"
      + datastore_id                            = "datastore-60"
      + default_ip_address                      = (known after apply)
      + ept_rvi_mode                            = "automatic"
      + extra_config                            = {
          + "guestinfo.metadata"          = "I2Nsb3VkLWNvbmZpZwpsb2NhbC1ob3N0bmFtZTogdm0KaW5zdGFuY2UtaWQ6IHRmLXZtCm5ldHdvcms6CiAgdmVyc2lvbjogMgogIGV0aGVybmV0czoKICAgIGVuczE5MjoKICAgICAgZGhjcDQ6IGZhbHNlCiAgICAgIGFkZHJlc3NlczoKICAgICAgICAtIDE5Mi4xNjguMTMuMjQ3LzIzCiAgICAgIGdhdGV3YXk0OiAxOTIuMTY4LjIuNQogICAgICBuYW1lc2VydmVyczoKICAgICAgICBhZGRyZXNzZXM6CiAgICAgICAgICAtIDguOC44LjgK"
          + "guestinfo.metadata.encoding" = "base64"
          + "guestinfo.userdata"          = "I2Nsb3VkLWNvbmZpZwpob3N0bmFtZTogdm0KZnFkbjogdm0ubG9jYWwKbWFuYWdlX2V0Y19ob3N0czogdHJ1ZQp1c2VyczoKICAtIG5hbWU6IHJvb3QKICAgIHN1ZG86IEFMTD0oQUxMKSBOT1BBU1NXRDpBTEwKICAgIGdyb3VwczogdXNlcnMsIGFkbWluLCBzdWRvCiAgICBob21lOiAvaG9tZS9yb290CiAgICBzaGVsbDogL2Jpbi9iYXNoCiAgICBsb2NrX3Bhc3N3ZDogZmFsc2UKICAgIHNzaC1hdXRob3JpemVkLWtleXM6CiAgICAgIC0gc3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCQVFDNWpZUkZlbDkrMTJxL3hTU0JmNDlZMllrWjYyTUZ6emNMcjFEOVFzblo5dzVqSys1ZTAzc1FBOXBQS3dKbkNuYnVFREdIMUoweFpqUTNjWjAzUVFyTEo5M2xGU2xSMnZBY1Y1bVhRdHRhUnphS0tGOFI2bWxQWGJ3b1FIeXNCSC8wM1c3MnNCWjJXT0xXem1ZTTRJSWdvWS93SlFvZFhtTlR3OTZqa244WCs4Y0hvZHg1NW0xSzgydFdCaEdkTWMzT2tpUzk4cXlKUjRuc1lScSszbEFiZC9hVVA4djdONGhTUDd6amhyZ1RhTzJqT3BuYkRKalhZdUs4V3lUL09lblF0YnpQc2RKY29tUEViRE4zdnRkOEhtZTlHWjBmcVMyUnJtaHBTenlkU2hiR0EreXRXNWg4MndyWEFLUVdJYWlpUzZ6TGloc0xkNG5BRmpJTllieEIKICAgCiAgLSBuYW1lOiBob2FuZ2hkIAogICAgc3VkbzogQUxMPShBTEwpIE5PUEFTU1dEOkFMTAogICAgZ3JvdXBzOiB1c2VycywgYWRtaW4sIHN1ZG8KICAgIGhvbWU6IC9ob21lL2hvYW5naGQKICAgIHNoZWxsOiAvYmluL2Jhc2gKICAgIGxvY2tfcGFzc3dkOiBmYWxzZQogCnNzaF9wd2F1dGg6IHRydWUKZGlzYWJsZV9yb290OiBmYWxzZQpjaHBhc3N3ZDoKICBsaXN0OiB8CiAgICAicm9vdCI6IkhvYW5naGQxNjQiCiAgICBob2FuZ2hkOkhvYW5naGQxNjQKICBleHBpcmU6IEZhbHNlCiAKYm9vdGNtZDoKICAtIHN1ZG8gdG91Y2ggL2V0Yy9jbG91ZC9jbG91ZC1pbml0LmRpc2FibGVkCg=="
          + "guestinfo.userdata.encoding" = "base64"
        }
      + firmware                                = "bios"
      + force_power_off                         = true
      + guest_id                                = "ubuntu64Guest"
      + guest_ip_addresses                      = (known after apply)
      + hardware_version                        = (known after apply)
      + host_system_id                          = (known after apply)
      + hv_mode                                 = "hvAuto"
      + id                                      = (known after apply)
      + ide_controller_count                    = 2
      + imported                                = (known after apply)
      + latency_sensitivity                     = "normal"
      + memory                                  = 4096
      + memory_limit                            = -1
      + memory_share_count                      = (known after apply)
      + memory_share_level                      = "normal"
      + migrate_wait_timeout                    = 30
      + moid                                    = (known after apply)
      + name                                    = "tf-vm"
      + num_cores_per_socket                    = 1
      + num_cpus                                = 2
      + power_state                             = (known after apply)
      + poweron_timeout                         = 300
      + reboot_required                         = (known after apply)
      + resource_pool_id                        = "resgroup-8"
      + run_tools_scripts_after_power_on        = true
      + run_tools_scripts_after_resume          = true
      + run_tools_scripts_before_guest_shutdown = true
      + run_tools_scripts_before_guest_standby  = true
      + sata_controller_count                   = 0
      + scsi_bus_sharing                        = "noSharing"
      + scsi_controller_count                   = 1
      + scsi_type                               = "pvscsi"
      + shutdown_wait_timeout                   = 3
      + storage_policy_id                       = (known after apply)
      + swap_placement_policy                   = "inherit"
      + tools_upgrade_policy                    = "manual"
      + uuid                                    = (known after apply)
      + vapp_transport                          = [
          + "iso",
        ]
      + vmware_tools_status                     = (known after apply)
      + vmx_path                                = (known after apply)
      + wait_for_guest_ip_timeout               = 0
      + wait_for_guest_net_routable             = true
      + wait_for_guest_net_timeout              = 0

      + cdrom {
          + client_device  = true
          + device_address = (known after apply)
          + key            = (known after apply)
        }

      + clone {
          + template_uuid = "4212a79e-568f-8a7e-925f-2d68e7a90040"
          + timeout       = 30
        }

      + disk {
          + attach            = false
          + controller_type   = "scsi"
          + datastore_id      = "<computed>"
          + device_address    = (known after apply)
          + disk_mode         = "persistent"
          + disk_sharing      = "sharingNone"
          + eagerly_scrub     = false
          + io_limit          = -1
          + io_reservation    = 0
          + io_share_count    = 0
          + io_share_level    = "normal"
          + keep_on_remove    = false
          + key               = 0
          + label             = "disk0"
          + path              = (known after apply)
          + size              = 10
          + storage_policy_id = (known after apply)
          + thin_provisioned  = true
          + unit_number       = 0
          + uuid              = (known after apply)
          + write_through     = false
        }

      + network_interface {
          + adapter_type          = "vmxnet3"
          + bandwidth_limit       = -1
          + bandwidth_reservation = 0
          + bandwidth_share_count = (known after apply)
          + bandwidth_share_level = "normal"
          + device_address        = (known after apply)
          + key                   = (known after apply)
          + mac_address           = (known after apply)
          + network_id            = "network-12"
        }
    }

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.

3. Terraform apply

Để triển khai virtual machine này, ta sử dụng command dưới với tham số -auto-approve để bỏ qua xác nhận.

terraform apply -auto-approve

Output

Plan: 1 to add, 0 to change, 0 to destroy.
vsphere_virtual_machine.allvms["vm"]: Creating...
vsphere_virtual_machine.allvms["vm"]: Still creating... [10s elapsed]
vsphere_virtual_machine.allvms["vm"]: Provisioning with 'file'...
vsphere_virtual_machine.allvms["vm"]: Still creating... [20s elapsed]
vsphere_virtual_machine.allvms["vm"]: Still creating... [30s elapsed]
vsphere_virtual_machine.allvms["vm"]: Still creating... [40s elapsed]
vsphere_virtual_machine.allvms["vm"]: Still creating... [50s elapsed]
vsphere_virtual_machine.allvms["vm"]: Still creating... [1m0s elapsed]
vsphere_virtual_machine.allvms["vm"]: Provisioning with 'remote-exec'...
vsphere_virtual_machine.allvms["vm"] (remote-exec): Connecting to remote host via SSH...
vsphere_virtual_machine.allvms["vm"] (remote-exec):   Host: 192.168.13.247
vsphere_virtual_machine.allvms["vm"] (remote-exec):   User: root
vsphere_virtual_machine.allvms["vm"] (remote-exec):   Password: false
vsphere_virtual_machine.allvms["vm"] (remote-exec):   Private key: true
vsphere_virtual_machine.allvms["vm"] (remote-exec):   Certificate: false
vsphere_virtual_machine.allvms["vm"] (remote-exec):   SSH Agent: false
vsphere_virtual_machine.allvms["vm"] (remote-exec):   Checking Host Key: false
vsphere_virtual_machine.allvms["vm"] (remote-exec):   Target Platform: unix
vsphere_virtual_machine.allvms["vm"] (remote-exec): Connected!
vsphere_virtual_machine.allvms["vm"] (remote-exec): Reading package lists... 100%
vsphere_virtual_machine.allvms["vm"] (remote-exec): Reading package lists... Done
vsphere_virtual_machine.allvms["vm"] (remote-exec): Building dependency tree... 100%
vsphere_virtual_machine.allvms["vm"] (remote-exec): Calculating upgrade... Done
vsphere_virtual_machine.allvms["vm"] (remote-exec): 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
vsphere_virtual_machine.allvms["vm"]: Creation complete after 1m51s [id=421229e2-6aec-6764-5b3e-7abd7d4d19f7]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Khi xem trên vCenter chúng ta đã thấy có 1 vm mới có tên tf-vm vừa được khởi tạo với ip address 192.168.13.247 đúng như chúng ta đã khai báo trong file cấu hình.

Kết quả khi login vào virtual machine bằng màn hình console

3. Terraform destroy

Để xóa virtual machine này, ta sử dụng command dưới và cũng sử dụng tham số -auto-approve để bỏ qua xác nhận.

terraform destroy -auto-approve

Output

Plan: 0 to add, 0 to change, 1 to destroy.
vsphere_virtual_machine.allvms["vm"]: Destroying... [id=421254d6-3427-860a-d4cd-b5b67091c4b1]
vsphere_virtual_machine.allvms["vm"]: Destruction complete after 9s

Destroy complete! Resources: 1 destroyed.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories