🖥️

Build, customize and deploy to vSphere

Posted on Wed, Jan 30, 2019 Automation

Automatic build Centos template for VMware vSphere with Builder and auto-deploy with Terraform or Ansible.

Packer

https://www.packer.io/

Packer is tool that automates the creation of a system image template. In this example, Packer creates Centos machine image for vSphere from a clean official ISO.

{
  "builders": [
    {
      "type": "vsphere-iso",

      "vcenter_server":      "vc.example.com",
      "username":            "[email protected]",
      "password":            "{{user `vsphere_password`}}",
      "insecure_connection": "true",
      "vm_name": "template-centos7-packer",
      "folder": "templates",
      "notes": "Build via Packer",
      "datacenter": "dc",
      "cluster": "cluster1",
      "host": "esx1.example.com",
      "datastore": "datastore1",
      "network": "lan",
      "resource_pool": "tier3",

      "guest_os_type": "centos7_64Guest",

      "ssh_username": "root",
      "ssh_password": "password",

      "CPUs":             1,
      "RAM":              1024,
      "RAM_reserve_all": false,

      "convert_to_template": true,

      "disk_controller_type":  "pvscsi",
      "disk_size":        10486,
      "disk_thin_provisioned": true,

      "network_card": "vmxnet3",
      "iso_paths": [
        "[datastore1] /_ISO/CentOS-7-x86_64-Minimal-1908.iso"
      ],
      "iso_checksum": "7002b56184180591a8fa08c2fe0c7338",
      "iso_checksum_type": "md5",
      "floppy_files": [
        "{{template_dir}}/ks.cfg"
      ],
      "boot_command": " <esc> <wait> linux inst.text inst.ks=hd:fd0:/ks.cfg <enter> " 
          }
  ]
}
install
lang en_US.UTF-8
keyboard us
timezone Europe/Prague
auth --useshadow --enablemd5
services --enabled=NetworkManager,sshd
eula --agreed
ignoredisk --only-use=sda
reboot

zerombr
bootloader --location=mbr
network --onboot yes --device ens192 --bootproto dhcp --noipv6


clearpart --all --initlabel
part swap --asprimary --fstype="swap" --size=1024
part /boot --fstype=xfs --size=200
part pv.01 --size=1 --grow
volgroup vg1 pv.01
logvol / --fstype xfs --name=root --vgname=vg1 --size=1 --grow

authconfig --enableshadow --passalgo=sha256
rootpw --iscrypted $5$cnxfyyiayqjelmbt$4/Lq1vPDBp2BZznXcLukwVy4n0DPp6tX.PrCz7YA62B

firewall --disabled
selinux --disabled

%packages
@core
%end

%post
yum -y install open-vm-tools perl
systemctl enable vmtoolsd
systemctl start vmtoolsd
%end
packer build -var vsphere_password=yourpassword centos.json

Deploy with Terraform

https://www.terraform.io/

When we have template. We can deploy as mirtual machine to VMware vSphere.

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install terraform
#====================#
# vCenter connection #
#====================#

variable "vsphere_user" {
  description = "vSphere user name"
}

variable "vsphere_password" {
  description = "vSphere password"
}

variable "vsphere_vcenter" {
  description = "vCenter server FQDN or IP"
}

variable "vsphere_unverified_ssl" {
  description = "Is the vCenter using a self signed certificate (true/false)"
}

variable "vsphere_datacenter" {
  description = "vSphere datacenter"
}

variable "vsphere_cluster" {
  description = "vSphere cluster"
  default     = ""
}

#=========================#
# vSphere virtual machine #
#=========================#

variable "vm_datastore" {
  description = "Datastore used for the vSphere virtual machines"
}

variable "vm_network" {
  description = "Network used for the vSphere virtual machines"
}

variable "vm_template" {
  description = "Template used to create the vSphere virtual machines"
}

variable "vm_linked_clone" {
  description = "Use linked clone to create the vSphere virtual machine from the template (true/false). If you would like to use the linked clone feature, your template need to have one and only one snapshot"
  default = "false"
}

variable "vm_ip" {
  description = "Ip used for the vSpgere virtual machine"
}

variable "vm_netmask" {
  description = "Netmask used for the vSphere virtual machine (example: 24)"
}

variable "vm_gateway" {
  description = "Gateway for the vSphere virtual machine"
}

variable "vm_dns" {
  description = "DNS for the vSphere virtual machine"
}

variable "vm_domain" {
  description = "Domain for the vSphere virtual machine"
}

variable "vm_cpu" {
  description = "Number of vCPU for the vSphere virtual machines"
}

variable "vm_ram" {
  description = "Amount of RAM for the vSphere virtual machines (example: 2048)"
}

variable "vm_name" {
  description = "The name of the vSphere virtual machines and the hostname of the machine"
}

variable "ssh-pub-key" {
  description = "The name of the vSphere virtual machines and the hostname of the machine"
}


variable "admin_password" {}
#===============================================================================
# vSphere Provider
#===============================================================================

provider "vsphere" {
  version        = "1.11.0"
  vsphere_server = "${var.vsphere_vcenter}"
  user           = "${var.vsphere_user}"
  password       = "${var.vsphere_password}"

  allow_unverified_ssl = "${var.vsphere_unverified_ssl}"
}

#===============================================================================
# vSphere Data
#===============================================================================

data "vsphere_datacenter" "dc" {
  name = "${var.vsphere_datacenter}"
}

data "vsphere_compute_cluster" "cluster" {
  name          = "${var.vsphere_cluster}"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

data "vsphere_datastore" "datastore" {
  name          = "${var.vm_datastore}"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

data "vsphere_network" "network" {
  name          = "${var.vm_network}"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

data "vsphere_virtual_machine" "template" {
  name          = "${var.vm_template}"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

#===============================================================================
# vSphere Resources
#===============================================================================

resource "vsphere_virtual_machine" "standalone" {
  name             = "${var.vm_name}"
  resource_pool_id = "${data.vsphere_compute_cluster.cluster.resource_pool_id}"
  datastore_id     = "${data.vsphere_datastore.datastore.id}"

  num_cpus = "${var.vm_cpu}"
  memory   = "${var.vm_ram}"
  guest_id = "${data.vsphere_virtual_machine.template.guest_id}"

  network_interface {
    network_id   = "${data.vsphere_network.network.id}"
    adapter_type = "${data.vsphere_virtual_machine.template.network_interface_types[0]}"
  }

  disk {
    label            = "${var.vm_name}.vmdk"
    size             = "${data.vsphere_virtual_machine.template.disks.0.size}"
    eagerly_scrub    = "${data.vsphere_virtual_machine.template.disks.0.eagerly_scrub}"
    thin_provisioned = "${data.vsphere_virtual_machine.template.disks.0.thin_provisioned}"
  }

  clone {
    template_uuid = "${data.vsphere_virtual_machine.template.id}"
    linked_clone  = "${var.vm_linked_clone}"

    customize {
      timeout = "20"

      linux_options {
        host_name = "${var.vm_name}"
        domain    = "${var.vm_domain}"
      }

      network_interface {
        ipv4_address = "${var.vm_ip}"
        ipv4_netmask = "${var.vm_netmask}"
      }

      ipv4_gateway    = "${var.vm_gateway}"
      dns_server_list = ["${var.vm_dns}"]
    }
  }
  provisioner "remote-exec" {
    inline = [
      "systemd-machine-id-setup",
      "mkdir /root/.ssh",
      "touch /root/.ssh/authorized_keys",
      "echo ${var.ssh-pub-key} >> /root/.ssh/authorized_keys",
      "chown root:root -R /root/.ssh",
      "chmod 700 /root/.ssh",
      "chmod 600 /root/.ssh/authorized_keys",
      "passwd --lock root",
      "yum update -y"
    ]
  }
  connection {
    host     = "${self.default_ip_address}"
    type     = "ssh"
    user     = "root"
    password = "${var.admin_password}"
}
}
terraform init
vim terraform.tfvars
terraform apply

Deploy with Ansible

https://www.ansible.com/

Alternatively you can deploy prepared template with Ansible

git clone [email protected]:pavmik/centos-deploy-vsphere.git
cd ansible 
ansible-playbook -i inventory playbook.yml
packer build -var vsphere_password=yourpassword centos.json

Automatic build Centos template for VMware vSphere with Packer and auto-deploy it with Terraform or Ansible.