Packer and ShieldedVM support

Rafael Alvarez
Google Cloud - Community
2 min readJun 5, 2020

Shielded VMs is a great tool from Google Cloud Platform (gcp) which allows you to have custom images, pre approved, baked and shielded (unmodifiable), ready to be provisioned within Google Compute Engine (gce).

Shielded VMs work great when use in conjunction of constraints/compute.requireShieldedVm constraint from Organization Policies.

Packer on the other side is a great tool to handle and manage the creation and maintenance of custom images across different cloud providers.

In order to bake a new image Packer has a wide variety of “builders”. The objective for a builder is to deploy and provision a VM within the chosen cloud (gce). After the vm is provisioned the builder is also responsible for the creation of a new image based on the disk previously configured.

Packer architecture and workflow

The downside to use Packer as a tool to provision and manage images in gcp is that it does not have the ability to interface with Shielded VMs. In other words, the googlecompute builder lacks the ability to create shielded images based on Shielded VMs.

In order to overcome this obstacle, I made a little tweak on Packer’s source code.

To begin with, one must understand the Packer inner architecture as well as it’s limitations.

Packer relies on go and existing cloud libraries provided by the official counterparts (in our case it’s the google project).

After careful consideration, I’ve found that google already provides (at it’s go library level) support for Shielded VMs. As such, the only thing left to do is to enable them at the Packer layer.

For that you might want to look at the gcp provisioner file located at packer/builder/googlecompute/driver_gce.go.

If you look closely enough you’ll see that there’s no configuration block for Shielded VM. Again, what’s needed to enable it is to add the following configuration block:

ShieldedInstanceConfig: &compute.ShieldedInstanceConfig{
EnableSecureBoot: true,
EnableVtpm: true,
EnableIntegrityMonitoring: true,
}

I know this can be embellished by adding variables instead of hard code them. But you have got to remember, this is done to validate the feasibility of using Packer as a management tool for Shielded VMs within gcp.

I’ll leave you with the diff so that you can go ahead and patch your copy of Packer code, build it and use it to provision custom Shielded VM images within gce.

diff --git a/builder/googlecompute/driver_gce.go b/builder/googlecompute/driver_gce.go
index f2adaa591..82761d129 100644
--- a/builder/googlecompute/driver_gce.go
+++ b/builder/googlecompute/driver_gce.go
@@ -420,6 +420,11 @@ func (d *driverGCE) RunInstance(c *InstanceConfig) (<-chan error, error) {
Tags: &compute.Tags{
Items: c.Tags,
},
+ ShieldedInstanceConfig: &compute.ShieldedInstanceConfig{
+ EnableSecureBoot: true,
+ EnableVtpm: true,
+ EnableIntegrityMonitoring: true,
+ },
}
d.ui.Message("Requesting instance creation...")

In order to pull this feat off you might want to refer to Packer’s official documentation on how to build and contribute with the project.

--

--

Rafael Alvarez
Google Cloud - Community

Proactive and highly responsible DevOps SME with vast experience in Information Technology and Computer Security along with background in Operational Research.