Packer is an open source tool for creating identical Virtual Machine (VM) images for multiple platforms from a single source configuration. This page explains how to use Packer and Cloud Build to create a VM image for use on Compute Engine.
Before you begin
The instructions on this page assume that you are familiar with Packer
. In addition:
- Have your source code including the Packer template handy.
- Have a Docker repository in Artifact Registry or create a new repository .
- If you want to use the
gcloudcommands in this page, install the Google Cloud CLI . -
Enable the following APIs:
gcloud services enable compute . googleapis . com gcloud services enable servicemanagement . googleapis . com gcloud services enable storage - api . googleapis . com gcloud services enable artifactregistry . googleapis . com
Required IAM permissions
-
To use Packer with Cloud Build, grant the Compute Engine Instance Admin (v1) role (
roles/compute.instanceAdmin.v1) and the Service Account User role (roles/iam.serviceAccountUser) to your build service account. -
To store built images in Artifact Registry, grant the Artifact Registry Writer role (
roles/artifactregistry.writer) to your build service account.
Creating a Packer builder image
Cloud Build provides a Packer community builder image
that you can use to invoke packer
commands in Cloud Build.
Before using this builder in a Cloud Build config file, you must build
the image and push it to Artifact Registry:
-
Clone the cloud-builders-community repository:
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git -
Navigate to the Packer builder image:
cd cloud-builders-community/packer -
Submit the builder to your project:
gcloud builds submit . --config cloudbuild.yaml --substitutions=_AR_HOST=[LOCATION]-docker.pkg.dev,_AR_REPO=[REPOSITORY]Where:
-
[LOCATION]is the region of your Artifact Registry repository. -
[REPOSITORY]is the name of your Artifact Registry repository.
-
Creating a Packer template
Create a new file named packer.pkr.hcl
and add the template configuration.
The following example shows a Packer template ( packer.pkr.hcl
) configured to build a Compute Engine VM image:
packer
{
required_plugins
{
googlecompute
=
{
version
=
">= 1.1.1"
source
=
"github.com/hashicorp/googlecompute"
}
}
}
variable
"image_name"
{
type
=
string
description
=
"The name of the output VM image"
default
=
"my-packer-image"
}
variable
"project_id"
{
type
=
string
description
=
"The GCP project ID"
}
variable
"image_family"
{
type
=
string
description
=
"The family of the output VM image"
default
=
"my-image-family"
}
variable
"image_zone"
{
type
=
string
description
=
"The zone to build the image in"
default
=
"us-central1-a"
}
source
"googlecompute" "gce"
{
project_id
=
var.project_id
source_image_family
=
"ubuntu-2004-lts"
source_image_project_ids
=
[
"ubuntu-os-cloud"
]
zone
=
var.image_zone
ssh_username
=
"packer"
machine_type
=
"e2-small"
image_name
=
"${var.image_name}-"
image_family
=
var.image_family
}
build
{
name
=
"gce-vm-image"
sources
=
[
"sources.googlecompute.gce"
]
provisioner
"shell"
{
inline
=
[
"echo 'Provisioning image...'"
,
"sudo apt-get update"
,
"sudo apt-get install -y nginx"
]
}
}
Using the Packer builder
-
Ensure that you have your Packer template (for example,
packer.pkr.hcl) along with your source code. -
In your project root directory, create a build config file named
cloudbuild.yamlorcloudbuild.json. -
In your build config file, add a build step to invoke the
packer buildcommand:YAML
steps : - name : '[LOCATION]-docker.pkg.dev/[PROJECT_ID]/[REPOSITORY]/packer' args : - build - -var - image_name=[IMAGE_NAME] - -var - project_id=[PROJECT_ID] - -var - image_family=[IMAGE_FAMILY] - -var - image_zone=[IMAGE_ZONE] - packer.pkr.hclJSON
{ "steps" : [ { "name" : "[LOCATION]-docker.pkg.dev/[PROJECT_ID]/[REPOSITORY]/packer" , "args" : [ "build" , "-var" , "image_name=[IMAGE_NAME]" , "-var" , "project_id=[PROJECT_ID]" , "-var" , "image_family=[IMAGE_FAMILY]" , "-var" , "image_zone=[IMAGE_ZONE]" , "packer.pkr.hcl" ] } ] }Where:
-
[LOCATION]is the region of your Artifact Registry repository. -
[PROJECT_ID]is your Google Cloud project ID. -
[REPOSITORY]is the name of your Artifact Registry repository. -
[IMAGE_NAME]is the name of the VM image you're building. -
[IMAGE_FAMILY]is the image family of the VM image. -
[IMAGE_ZONE]is the image zone .
-
-
Start the build using the build config file:
gcloud builds submit --region=[REGION] --config [CONFIG_FILE_PATH] [SOURCE_DIRECTORY]Where:
-
[CONFIG_FILE_PATH]is the path to the build config file. -
[SOURCE_DIRECTORY]is the path or URL to the source code. -
[REGION]is one of the supported build regions .
If you don't specify a
[CONFIG_FILE_PATH]and[SOURCE_DIRECTORY]in thegcloud builds submitcommand, Cloud Build assumes that the config file and the source code are in the current working directory. -
Once the images are built, you can view them in the Compute Engine Image page in the Google Cloud console.
What's next
- Learn how to build containers .
- Learn how to build
Goprojects . - Learn how to troubleshoot build errors .

