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.