Build an incremental OVA from a VM template using Packer

Hola, folks! Another day at office and another use-case to be documented…

I am sure most of you must have already been already introduced to Packer. I, first hand, experienced what it could do to help operationalising an environment. Just in case, if you haven’t learnt about it yet, as the saying goes: “Its never too late, y’all”.

So, this is from where you can learn more about Packer, an open-source tool to create/replicate your machine images across platforms. For the context of this article, I am going to stick to the vSphere platform.

Pre-requisites:

  • A linux virtual machine
  • vCenter Server (I will be using vCenter 7.0 for the demo)
  • A Virtual Machine template
  • Content Library

Packer Installation:

I used the public documentation to install packer on a CentOS machine that I was going to use to create these incremental OVAs.

To verify the installation you can just run packer and you should be able to see the following output.

Packer-vSphere Plugin:

Before I get into the specifics of how I built the OVA, I would like to describe a bit about how this works behind the scenes.

Packer uses a template to build images. I will be running packer commands from the path where these templates sit. This is not a hard requirement. You can specify a path to your template if you are running the command from elsewhere. That said, what do these templates have?

Earlier, packer used to work with these templates being json. Now, HCL is the defacto format for the templates. HCL is HashiCorp Configuration Language. This template consists of different blocks: source, build and provision. Though there are a few more, we will be discussing primarily about these 3 blocks.

Packer uses external plugins to integrate with various cloud platforms and our topic of discussion for today would be the vSphere plugin. The vSphere plugin/builder has 3 builders namely vsphere-iso, vsphere-clone, vsphere-supervisor.

  • vsphere-iso – To build an image from scratch using an ISO that’s already uploaded to the vSphere environment.
  • vsphere-clone – To clone from an existing template (and do more with the cloned machine.. :D)
  • vsphere-supervisor – An alternative to deploying VMs declaratively using the VMService APIs in a vSphere with Tanzu environment. You can say good-bye to your YAML files.. Not so cool though, you will still have to create the HCL template 😛

As you might have guessed already, I will be using the vsphere-clone builder for this exercise.

Packer Template:

I used the open source example as a reference to build my template. The example I have linked here, just uses a vSphere template to provision a new VM. But that wasn’t what I wanted to do. So I kept exploring the clone builder and that’s when I figured there is a lot more to it than what was mentioned in the example.

So my final templates looks like something below.

template.pkr.hcl

locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
source "vsphere-clone" "example_clone" {
communicator = var.communicator
host = var.host
insecure_connection = var.insecure_connection
password = var.password
template = var.template
username = var.username
vcenter_server = var.vcenter_server
vm_name = var.vm_name
content_library_destination {
library = "VMService"
name = "centos-ova"
ovf = "true"
destroy = "true"
}
}
build {
sources = ["source.vsphere-clone.example_clone"]
}

If you notice, I had specified the vCenter Server and other necessary variables using “var.”. So, this needs to be defined in a separate variable file (makes no sense to me though 🙂 ). I have named these files as variables.pkr.hcl and vars.auto.pkvars.hcl.

variables.pkr.hcl

variable "vcenter_server" {
  type    = string
  default = ""
}

variable "username" {
  type    = string
  default = ""
}

variable "password" {
  type    = string
  default = ""
}

variable "communicator" {
  type    = string
  default = ""
}

variable "host" {
  type    = string
  default = ""
}

variable "template" {
  type    = string
  default = ""
}

variable "vm_name" {
  type    = string
  default = ""
}
variable "insecure_connection" {
  type    = string
  default = ""
}

vars.auto.pkvars.hcl

communicator = "none"
host = "192.168.xx.xx"
insecure_connection = "true"
password = "***********"
template = "ubuntu14"
username = "administrator@vsphere.local"
vcenter_server = "192.168.xx.xx"
vm_name = "centos-clone-{{timestamp}}"

And, now I am ready to build my image. All I have to do is run “packer build .”. Packer would then pickup the template and variable files and create an image for me. Before I do that, here’s a snippet of my content library before running the command.

As soon as you run the build command, you see the output as shown below.

And in the vCenter, you should see clone and content library upload messages as shown below.

And finally, here’s what I see in my “VMService” Content Library.

Here is a screenshot of my “VMs and Templates” inventory view as well. This confirms the cloned VM has been destroyed.

That’s it for today folks. I will follow this up with a “Provisioner” template to demonstrate how powerful it is, if you need to customise your ova once its is built. I haven’t explored the vsphere-supervisor builder yet. Hope to do it sometime soon and if its worth it, may be I will write about it too.

Feel free to hit me up with any questions/concerns that you might have! Happy to discuss and learn. Would love to hear all your feedback 🙂

“If you don’t share what you learn, then what’s even the point of learning :)”

Please follow and like my content:

2 comments

Leave a Reply

Your email address will not be published. Required fields are marked *

error

Enjoy this blog? Please spread the word :)