Terraform is one of the Infrastructure as code (IaC) tools to automate deployment in cloud / on premises. Compare with AWS and Azure, which has their own IaC language (e.g. AWS cloudformation), but Terraform is more general purpose on multiple cloud environment. Terraform wrote in HashiCorp Configuration Language (HCL), which similar to YAML; but compare with other IaC (e.g. Pulumi), it cannot present complex infrastructure environment in code level even it has limited function; Also it is inconvenience on configuration management so Terraform need to work with other CD solution (e.g. Ansible). Even so, Terraform has a number of providers still make it can be one of the common used IaC tools.This demo will show how to use Terraform to create Ubuntu 22.0.4 as guest OS in ESXi server. Even though VMWare has their own provider, but it required vsphere license for it API. So this case will use another provider josenk/esxi
to implement changes via Terraform.
- Setup Terraform provider.
In text editor create a file namedversions.tf
and input content below.terraform { required_version = ">= 1.2.5" required_providers { esxi = { source = "registry.terraform.io/josenk/esxi" } } }
- Setup variable.
In text editor create a file namedvariables.tf
and input content below.variable "esxi_hostname" { description = "ESXI server host name." } variable "esxi_hostport" { description = "ESXI server port." default = "22" } variable "esxi_hostssl" { description = "ESXI server SSH port." default = "443" } variable "esxi_username" { description = "ESXI server user name." default = "root" } variable "esxi_password" { # Unspecified will prompt description = "ESXI server password." sensitive = true } variable "default_password" { type = string sensitive = true } variable "nodes" { type = list(string) description = "Names of VMs to be create." # Example value. default = ["vm-k8s-sr01", "vm-k8s-sr02", "vm-k8s-sr03"] } variable "ssh_public_key_path" { type = string description = "ssh public key which will set in guest OS for remote execute command." } variable "ssh_private_key_path" { type = string description = "ssh private key which will use to remote execute command." sensitive = true } variable "default-ssh-user" { type = string default = "ubuntu" } provider "esxi" { esxi_hostname = var.esxi_hostname esxi_hostport = var.esxi_hostport esxi_hostssl = var.esxi_hostssl esxi_username = var.esxi_username esxi_password = var.esxi_password }
- Setup resource.
In text editor create a file namedmain.tf
and input content below.resource "random_id" "instance_id" { byte_length = 8 } resource "esxi_guest" "default" { count = length(var.node_list) guest_name = var.node_list[count.index] numvcpus = var.esxi_vm_guest_default_settings.numvcpus memsize = var.esxi_vm_guest_default_settings.memsize boot_disk_size = var.esxi_vm_guest_default_settings.boot_disk_size disk_store = var.esxi_vm_guest_default_settings.disk_store network_interfaces { virtual_network = var.esxi_vm_guest_default_settings.virtual_network } ovf_source = "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.ova" ovf_properties { key = "instance-id" value = random_id.instance_id.hex } ovf_properties { key = "hostname" value = var.node_list[count.index] } ovf_properties { key = "password" value = var.default_password } ovf_properties { key = "public-keys" value = var.ssh_public_key } provisioner "file" { source = "c:\\scripts\.24.3\\common.sh" destination = "/tmp/common.sh" connection { type = "ssh" host = self.ip_address user = local.default-ssh-user timeout = "15s" private_key = var.ssh_private_key agent = false } } provisioner "remote-exec" { connection { type = "ssh" host = self.ip_address user = var.default-ssh-user timeout = "15s" private_key = var.ssh_private_key agent = false } inline = [ "echo '${var.default_password}' | sudo -S hostnamectl set-hostname ${var.node_list[count.index]}", "echo '${var.default_password}' | sudo -S apt update", "echo '${var.default_password}' | sudo -S apt upgrade -y", "echo '${var.default_password}' | sudo -S apt clean" ] } }
- Implement in terraform.
In command prompt, go to file directory and execute command below.terraform init terraform plan terraform approve -autoapprove
- Verify result.
In target ESXi server, check created VM exists or not.
Terraform HCL has been push to GitHub repository. But it is pack as module and there has some optimization for my home lab use.
Leave a Reply