Google Compute Builder
Type: googlecompute
The googlecompute
Packer builder is able to create
images for use with
Google Compute Engine (GCE)
based on existing images.
It is possible to build images from scratch, but not with the googlecompute
Packer builder. The process is recommended only for advanced users, please see
Building GCE Images from Scratch
and the Google Compute Import
Post-Processor for more
information.
Authentication
Authenticating with Google Cloud services requires either a User Application Default Credentials
or a JSON Service Account Key. These are not required if you are
running the googlecompute
Packer builder on Google Cloud with a
properly-configured Google Service
Account.
Running locally on your workstation.
If you run the googlecompute
Packer builder locally on your workstation, you will
need to install the Google Cloud SDK and authenticate using User Application Default
Credentials.
You don't need to specify an account file if you are using this method. Your user
must have at least Compute Instance Admin (v1)
& Service Account User
roles
to use Packer succesfully.
Running on Google Cloud
If you run the googlecompute
Packer builder on GCE or GKE, you can
configure that instance or cluster to use a Google Service
Account. This will allow
Packer to authenticate to Google Cloud without having to bake in a separate
credential/authentication file.
It is recommended that you create a custom service account for Packer and assign it
Compute Instance Admin (v1)
& Service Account User
roles.
For gcloud
, you can run the following commands:
$ gcloud iam service-accounts create packer \
--project YOUR_GCP_PROJECT \
--description="Packer Service Account" \
--display-name="Packer Service Account"
$ gcloud projects add-iam-policy-binding YOUR_GCP_PROJECT \
--member=serviceAccount:packer@YOUR_GCP_PROJECT.iam.gserviceaccount.com \
--role=roles/compute.instanceAdmin.v1
$ gcloud projects add-iam-policy-binding YOUR_GCP_PROJECT \
--member=serviceAccount:packer@YOUR_GCP_PROJECT.iam.gserviceaccount.com \
--role=roles/iam.serviceAccountUser
$ gcloud compute instances create INSTANCE-NAME \
--project YOUR_GCP_PROJECT \
--image-family ubuntu-2004-lts \
--image-project ubuntu-os-cloud \
--network YOUR_GCP_NETWORK \
--zone YOUR_GCP_ZONE \
--service-account=packer@YOUR_GCP_PROJECT.iam.gserviceaccount.com \
--scopes="https://www.googleapis.com/auth/cloud-platform"
The service account will be used automatically by Packer as long as there is no account file specified in the Packer configuration file.
Running outside of Google Cloud
The Google Cloud Console allows
you to create and download a credential file that will let you use the
googlecompute
Packer builder anywhere. To make the process more
straightforwarded, it is documented here.
Log into the Google Cloud Console and select a project.
Click Select a project, choose your project, and click Open.
Click Create Service Account.
Enter a service account name (friendly display name), an optional description, select the
Compute Engine Instance Admin (v1)
andService Account User
roles, and then click Save.Generate a JSON Key and save it in a secure location.
Set the Environment Variable
GOOGLE_APPLICATION_CREDENTIALS
to point to the path of the service account key.
Precedence of Authentication Methods
Packer looks for credentials in the following places, preferring the first location found:
An
account_file
option in your packer file.A JSON file (Service Account) whose path is specified by the
GOOGLE_APPLICATION_CREDENTIALS
environment variable.A JSON file in a location known to the
gcloud
command-line tool. (gcloud auth application-default login
creates it)On Windows, this is:
%APPDATA%/gcloud/application_default_credentials.json
On other systems:
$HOME/.config/gcloud/application_default_credentials.json
On Google Compute Engine and Google App Engine Managed VMs, it fetches credentials from the metadata server. (Needs a correct VM authentication scope configuration, see above.)
Examples
Basic Example
Below is a fully functioning example. It doesn't do anything useful since no provisioners or startup-script metadata are defined, but it will effectively repackage an existing GCE image.
{
"builders": [
{
"type": "googlecompute",
"project_id": "my project",
"source_image": "debian-9-stretch-v20200805",
"ssh_username": "packer",
"zone": "us-central1-a"
}
]
}
Windows Example
Before you can provision using the winrm communicator, you need to allow traffic through google's firewall on the winrm port (tcp:5986). You can do so using the gcloud command.
gcloud compute firewall-rules create allow-winrm --allow tcp:5986
Or alternatively by navigating to https://console.cloud.google.com/networking/firewalls/list.
Once this is set up, the following is a complete working packer config after
setting a valid project_id
:
{
"builders": [
{
"type": "googlecompute",
"project_id": "my project",
"source_image": "windows-server-2019-dc-v20200813",
"disk_size": "50",
"machine_type": "n1-standard-2",
"communicator": "winrm",
"winrm_username": "packer_user",
"winrm_insecure": true,
"winrm_use_ssl": true,
"metadata": {
"windows-startup-script-cmd": "winrm quickconfig -quiet & net user /add packer_user & net localgroup administrators packer_user /add & winrm set winrm/config/service/auth @{Basic=\"true\"}"
},
"zone": "us-central1-a"
}
]
}
Warning: Please note that if you're setting up WinRM for provisioning, you'll probably want to turn it off or restrict its permissions as part of a shutdown script at the end of Packer's provisioning process. For more details on the why/how, check out this useful blog post and the associated code: https://cloudywindows.io/post/winrm-for-provisioning-close-the-door-on-the-way-out-eh/
This build can take up to 15 min.
Nested Hypervisor Example
This is an example of using the image_licenses
configuration option to create
a GCE image that has nested virtualization enabled. See Enabling Nested
Virtualization for VM
Instances
for details.
{
"builders": [
{
"type": "googlecompute",
"project_id": "my project",
"source_image_family": "centos-7",
"ssh_username": "packer",
"zone": "us-central1-a",
"image_licenses": ["projects/vm-options/global/licenses/enable-vmx"]
}
]
}
Shared VPC Example
This is an example of using the network_project_id
configuration option to create
a GCE instance in a Shared VPC Network. See Creating a GCE Instance using Shared
VPC
for details. The user/service account running Packer must have Compute Network User
role on
the Shared VPC Host Project to create the instance in addition to the other roles mentioned in the
Running on Google Cloud section.
{
"builders": [
{
"type": "googlecompute",
"project_id": "my project",
"subnetwork": "default",
"source_image_family": "centos-7",
"network_project_id": "SHARED_VPC_PROJECT",
"ssh_username": "packer",
"zone": "us-central1-a",
"image_licenses": ["projects/vm-options/global/licenses/enable-vmx"]
}
]
}
Configuration Reference
Configuration options are organized below into two categories: required and optional. Within each category, the available options are alphabetized and described.
In addition to the options listed here, a communicator can be configured for this builder.
Communicator Configuration
Optional:
communicator
(string) - Packer currently supports three kinds of communicators:none
- No communicator will be used. If this is set, most provisioners also can't be used.ssh
- An SSH connection will be established to the machine. This is usually the default.winrm
- A WinRM connection will be established.
In addition to the above, some builders have custom communicators they can use. For example, the Docker builder has a "docker" communicator that uses
docker exec
anddocker cp
to execute scripts and copy files.pause_before_connecting
(duration string | ex: "1h5m2s") - We recommend that you enable SSH or WinRM as the very last step in your guest's bootstrap script, but sometimes you may have a race condition where you need Packer to wait before attempting to connect to your guest.If you end up in this situation, you can use the template option
pause_before_connecting
. By default, there is no pause. For example if you setpause_before_connecting
to10m
Packer will check whether it can connect, as normal. But once a connection attempt is successful, it will disconnect and then wait 10 minutes before connecting to the guest and beginning provisioning.
ssh_host
(string) - The address to SSH to. This usually is automatically configured by the builder.ssh_port
(int) - The port to connect to SSH. This defaults to22
.ssh_username
(string) - The username to connect to SSH with. Required if using SSH.ssh_password
(string) - A plaintext password to use to authenticate with SSH.ssh_ciphers
([]string) - This overrides the value of ciphers supported by default by golang. The default value is [ "aes128-gcm@openssh.com", "chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", ]Valid options for ciphers include: "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "chacha20-poly1305@openssh.com", "arcfour256", "arcfour128", "arcfour", "aes128-cbc", "3des-cbc",
ssh_clear_authorized_keys
(bool) - If true, Packer will attempt to remove its temporary key from~/.ssh/authorized_keys
and/root/.ssh/authorized_keys
. This is a mostly cosmetic option, since Packer will delete the temporary private key from the host system regardless of whether this is set to true (unless the user has set the-debug
flag). Defaults to "false"; currently only works on guests withsed
installed.ssh_key_exchange_algorithms
([]string) - If set, Packer will override the value of key exchange (kex) altorighms supported by default by golang. Acceptable values include: "curve25519-sha256@libssh.org", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha1", and "diffie-hellman-group1-sha1".ssh_certificate_file
(string) - Path to user certificate used to authenticate with SSH. The~
can be used in path and will be expanded to the home directory of current user.ssh_pty
(bool) - Iftrue
, a PTY will be requested for the SSH connection. This defaults tofalse
.ssh_timeout
(duration string | ex: "1h5m2s") - The time to wait for SSH to become available. Packer uses this to determine when the machine has booted so this is usually quite long. Example value:10m
.ssh_disable_agent_forwarding
(bool) - If true, SSH agent forwarding will be disabled. Defaults tofalse
.ssh_handshake_attempts
(int) - The number of handshakes to attempt with SSH once it can connect. This defaults to10
.ssh_bastion_host
(string) - A bastion host to use for the actual SSH connection.ssh_bastion_port
(int) - The port of the bastion host. Defaults to22
.ssh_bastion_agent_auth
(bool) - Iftrue
, the local SSH agent will be used to authenticate with the bastion host. Defaults tofalse
.ssh_bastion_username
(string) - The username to connect to the bastion host.ssh_bastion_password
(string) - The password to use to authenticate with the bastion host.ssh_bastion_interactive
(bool) - Iftrue
, the keyboard-interactive used to authenticate with bastion host.ssh_bastion_private_key_file
(string) - Path to a PEM encoded private key file to use to authenticate with the bastion host. The~
can be used in path and will be expanded to the home directory of current user.ssh_bastion_certificate_file
(string) - Path to user certificate used to authenticate with bastion host. The~
can be used in path and will be expanded to the home directory of current user.ssh_file_transfer_method
(string) -scp
orsftp
- How to transfer files, Secure copy (default) or SSH File Transfer Protocol.ssh_proxy_host
(string) - A SOCKS proxy host to use for SSH connectionssh_proxy_port
(int) - A port of the SOCKS proxy. Defaults to1080
.ssh_proxy_username
(string) - The optional username to authenticate with the proxy server.ssh_proxy_password
(string) - The optional password to use to authenticate with the proxy server.ssh_keep_alive_interval
(duration string | ex: "1h5m2s") - How often to send "keep alive" messages to the server. Set to a negative value (-1s
) to disable. Example value:10s
. Defaults to5s
.ssh_read_write_timeout
(duration string | ex: "1h5m2s") - The amount of time to wait for a remote command to end. This might be useful if, for example, packer hangs on a connection after a reboot. Example:5m
. Disabled by default.ssh_remote_tunnels
([]string) -ssh_local_tunnels
([]string) -
ssh_private_key_file
(string) - Path to a PEM encoded private key file to use to authenticate with SSH. The~
can be used in path and will be expanded to the home directory of current user.
Required:
project_id
(string) - The project ID that will be used to launch instances and store images.source_image
(string) - The source image to use to create the new image from. You can also specify source_image_family instead. If both source_image and source_image_family are specified, source_image takes precedence. Example: "debian-8-jessie-v20161027"source_image_family
(string) - The source image family to use to create the new image from. The image family always returns its latest image that is not deprecated. Example: "debian-8".zone
(string) - The zone in which to launch the instance used to create the image. Example: "us-central1-a"
Optional:
account_file
(string) - The JSON file containing your account credentials. Not required if you run Packer on a GCE instance with a service account. Instructions for creating the file or using service accounts are above.impersonate_service_account
(string) - This allows service account impersonation as per the docs.accelerator_type
(string) - Full or partial URL of the guest accelerator type. GPU accelerators can only be used with"on_host_maintenance": "TERMINATE"
option set. Example:"projects/project_id/zones/europe-west1-b/acceleratorTypes/nvidia-tesla-k80"
accelerator_count
(int64) - Number of guest accelerator cards to add to the launched instance.address
(string) - The name of a pre-allocated static external IP address. Note, must be the name and not the actual IP address.disable_default_service_account
(bool) - If true, the default service account will not be used if service_account_email is not specified. Set this value to true and omit service_account_email to provision a VM with no service account.disk_name
(string) - The name of the disk, if unset the instance name will be used.disk_size
(int64) - The size of the disk in GB. This defaults to 10, which is 10GB.disk_type
(string) - Type of disk used to back your instance, like pd-ssd or pd-standard. Defaults to pd-standard.enable_secure_boot
(bool) - Create a Shielded VM image with Secure Boot enabled. It helps ensure that the system only runs authentic software by verifying the digital signature of all boot components, and halting the boot process if signature verification fails. Detailsenable_vtpm
(bool) - Create a Shielded VM image with virtual trusted platform module Measured Boot enabled. A vTPM is a virtualized trusted platform module, which is a specialized computer chip you can use to protect objects, like keys and certificates, that you use to authenticate access to your system. Detailsenable_integrity_monitoring
(bool) - Integrity monitoring helps you understand and make decisions about the state of your VM instances. Note: integrity monitoring relies on having vTPM enabled. Detailsskip_create_image
(bool) - Skip creating the image. Useful for setting totrue
during a build test stage. Defaults tofalse
.image_name
(string) - The unique name of the resulting image. Defaults topacker-{{timestamp}}
.image_description
(string) - The description of the resulting image.image_encryption_key
(*CustomerEncryptionKey) - Image encryption key to apply to the created image. Possible values:- kmsKeyName - The name of the encryption key that is stored in Google Cloud KMS.
- RawKey: - A 256-bit customer-supplied encryption key, encodes in RFC 4648 base64.
examples:
{ "kmsKeyName": "projects/${project}/locations/${region}/keyRings/computeEngine/cryptoKeys/computeEngine/cryptoKeyVersions/4" }
image_encryption_key { kmsKeyName = "projects/${var.project}/locations/${var.region}/keyRings/computeEngine/cryptoKeys/computeEngine/cryptoKeyVersions/4" }
image_family
(string) - The name of the image family to which the resulting image belongs. You can create disks by specifying an image family instead of a specific image name. The image family always returns its latest image that is not deprecated.image_labels
(map[string]string) - Key/value pair labels to apply to the created image.image_licenses
([]string) - Licenses to apply to the created image.image_storage_locations
([]string) - Storage location, either regional or multi-regional, where snapshot content is to be stored and only accepts 1 value. Always defaults to a nearby regional or multi-regional location.multi-regional example:
{ "image_storage_locations": ["us"] }
regional example:
{ "image_storage_locations": ["us-east1"] }
instance_name
(string) - A name to give the launched instance. Beware that this must be unique. Defaults topacker-{{uuid}}
.labels
(map[string]string) - Key/value pair labels to apply to the launched instance.machine_type
(string) - The machine type. Defaults to "n1-standard-1".metadata
(map[string]string) - Metadata applied to the launched instance. All metadata configuration values are expected to be of type string. Google metadata options that take a value ofTRUE
orFALSE
should be set as a string (i.e"TRUE"
"FALSE"
or"true"
"false"
).metadata_files
(map[string]string) - Metadata applied to the launched instance. Values are files.min_cpu_platform
(string) - A Minimum CPU Platform for VM Instance. Availability and default CPU platforms vary across zones, based on the hardware available in each GCP zone. Detailsnetwork
(string) - The Google Compute network id or URL to use for the launched instance. Defaults to "default". If the value is not a URL, it will be interpolated toprojects/((network_project_id))/global/networks/((network))
. This value is not required if a subnet is specified.network_project_id
(string) - The project ID for the network and subnetwork to use for launched instance. Defaults to project_id.omit_external_ip
(bool) - If true, the instance will not have an external IP. use_internal_ip must be true if this property is true.on_host_maintenance
(string) - Sets Host Maintenance Option. Valid choices areMIGRATE
andTERMINATE
. Please see GCE Instance Scheduling Options, as not all machine_types supportMIGRATE
(i.e. machines with GPUs). If preemptible is true this can only beTERMINATE
. If preemptible is false, it defaults toMIGRATE
preemptible
(bool) - If true, launch a preemptible instance.state_timeout
(duration string | ex: "1h5m2s") - The time to wait for instance state changes. Defaults to "5m".region
(string) - The region in which to launch the instance. Defaults to the region hosting the specified zone.scopes
([]string) - The service account scopes for launched instance. Defaults to:[ "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/compute", "https://www.googleapis.com/auth/devstorage.full_control" ]
service_account_email
(string) - The service account to be used for launched instance. Defaults to the project's default service account unless disable_default_service_account is true.source_image_project_id
([]string) - A list of project IDs to search for the source image. Packer will search the first project ID in the list first, and fall back to the next in the list, until it finds the source image.startup_script_file
(string) - The path to a startup script to run on the launched instance from which the image will be made. When set, the contents of the startup script file will be added to the instance metadata under the"startup_script"
metadata property. See Providing startup script contents directly for more details.When using
startup_script_file
the following rules apply:- The contents of the script file will overwrite the value of the
"startup_script"
metadata property at runtime. - The contents of the script file will be wrapped in Packer's startup script wrapper, unless
wrap_startup_script
is disabled. Seewrap_startup_script
for more details. - Not supported by Windows instances. See Startup Scripts for Windows for more details.
- The contents of the script file will overwrite the value of the
wrap_startup_script
(boolean) - For backwards compatibility this option defaults to"true"
in the future it will default to"false"
. If "true", the contents ofstartup_script_file
or"startup_script"
in the instance metadata is wrapped in a Packer specific script that tracks the execution and completion of the provided startup script. The wrapper ensures that the builder will not continue until the startup script has been executed.- The use of the wrapped script file requires that the user or service account running the build has the compute.instance.Metadata role.
subnetwork
(string) - The Google Compute subnetwork id or URL to use for the launched instance. Only required if the network has been created with custom subnetting. Note, the region of the subnetwork must match the region or zone in which the VM is launched. If the value is not a URL, it will be interpolated toprojects/((network_project_id))/regions/((region))/subnetworks/((subnetwork))
tags
([]string) - Assign network tags to apply firewall rules to VM instance.use_internal_ip
(bool) - If true, use the instance's internal IP instead of its external IP during building.use_os_login
(bool) - If true, OSLogin will be used to manage SSH access to the compute instance by dynamically importing a temporary SSH key to the Google account's login profile, and setting theenable-oslogin
toTRUE
in the instance metadata. Optionally,use_os_login
can be used with an existingssh_username
andssh_private_key_file
if a SSH key has already been added to the Google account's login profile - See Adding SSH Keys.SSH keys can be added to an individual user account
$ gcloud compute os-login ssh-keys add --key-file=/home/user/.ssh/my-key.pub $ gcloud compute os-login describe-profile PosixAccounts: - accountId: <project-id> gid: '34567890754' homeDirectory: /home/user_example_com ... primary: true uid: '2504818925' username: /home/user_example_com sshPublicKeys: 000000000000000000000000000000000000000000000000000000000000000a: fingerprint: 000000000000000000000000000000000000000000000000000000000000000a
Or SSH keys can be added to an associated service account
$ gcloud auth activate-service-account --key-file=<path to service account credentials file (e.g account.json)> $ gcloud compute os-login ssh-keys add --key-file=/home/user/.ssh/my-key.pub $ gcloud compute os-login describe-profile PosixAccounts: - accountId: <project-id> gid: '34567890754' homeDirectory: /home/sa_000000000000000000000 ... primary: true uid: '2504818925' username: sa_000000000000000000000 sshPublicKeys: 000000000000000000000000000000000000000000000000000000000000000a: fingerprint: 000000000000000000000000000000000000000000000000000000000000000a
vault_gcp_oauth_engine
(string) - Can be set instead of account_file. If set, this builder will use HashiCorp Vault to generate an Oauth token for authenticating against Google Cloud. The value should be the path of the token generator within vault. For information on how to configure your Vault + GCP engine to produce Oauth tokens, see https://www.vaultproject.io/docs/auth/gcp You must have the environment variables VAULT_ADDR and VAULT_TOKEN set, along with any other relevant variables for accessing your vault instance. For more information, see the Vault docs: https://www.vaultproject.io/docs/commands/#environment-variables Example:"vault_gcp_oauth_engine": "gcp/token/my-project-editor",
wait_to_add_ssh_keys
(duration string | ex: "1h5m2s") - The time to wait between the creation of the instance used to create the image, and the addition of SSH configuration, including SSH keys, to that instance. The delay is intended to protect packer from anything in the instance boot sequence that has potential to disrupt the creation of SSH configuration (e.g. SSH user creation, SSH key creation) on the instance. Note: All other instance metadata, including startup scripts, are still added to the instance during it's creation. Example value:5m
.
use_iap
(bool) - Whether to use an IAP proxy. Prerequisites and limitations for using IAP:- You must manually enable the IAP API in the Google Cloud console.
- You must have the gcloud sdk installed on the computer running Packer.
- You must be using a Service Account with a credentials file (using the account_file option in the Packer template)
- You must add the given service account to project level IAP permissions in https://console.cloud.google.com/security/iap. To do so, click "project" > "SSH and TCP resoures" > "All Tunnel Resources" > "Add Member". Then add your service account and choose the role "IAP-secured Tunnel User" and add any conditions you may care about.
iap_localhost_port
(int) - Which port to connect the local end of the IAM localhost proxy to. If left blank, Packer will choose a port for you from available ports.iap_hashbang
(string) - What "hashbang" to use to invoke script that sets up gcloud. Default: "/bin/sh"iap_ext
(string) - What file extension to use for script that sets up gcloud. Default: ".sh"iap_tunnel_launch_wait
(int) - How long to wait, in seconds, before assuming a tunnel launch was successful. Defaults to 30 seconds for SSH or 40 seconds for WinRM.
Startup Scripts
Startup scripts can be a powerful tool for configuring the instance from which
the image is made. The builder will wait for a startup script to terminate. A
startup script can be provided via the startup_script_file
or
startup-script
instance creation metadata
field. Therefore, the build time
will vary depending on the duration of the startup script. If
startup_script_file
is set, the startup-script
metadata
field will be
overwritten. In other words, startup_script_file
takes precedence.
The builder does check for a pass/fail/error signal from the startup
script by tracking the startup-script-status
metadata. Packer will check if this key
is set to done and if it not set to done before the timeout, Packer will fail the build.
Windows
A Windows startup script can only be provided via the
windows-startup-script-cmd
instance creation metadata
field. The builder
will not wait for a Windows startup script to terminate. You have to ensure
that it finishes before the instance shuts down.
Logging
Startup script logs can be copied to a Google Cloud Storage (GCS) location
specified via the startup-script-log-dest
instance creation metadata
field.
The GCS location must be writeable by the service account of the instance that Packer created.
Temporary SSH keypair
When no ssh credentials are specified, Packer will generate a temporary SSH keypair for the instance, you can change the algorithm type and bits settings.
Optional:
temporary_key_pair_type
(string) -dsa
|ecdsa
|ed25519
|rsa
( the default )Specifies the type of key to create. The possible values are 'dsa', 'ecdsa', 'ed25519', or 'rsa'.
temporary_key_pair_bits
(int) - Specifies the number of bits in the key to create. For RSA keys, the minimum size is 1024 bits and the default is 4096 bits. Generally, 3072 bits is considered sufficient. DSA keys must be exactly 1024 bits as specified by FIPS 186-2. For ECDSA keys, bits determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will fail. Ed25519 keys have a fixed length and bits will be ignored.
Gotchas
CentOS and recent Debian images have root ssh access disabled by default. Set
ssh_username
to any user, which will be created by packer with sudo access.
The machine type must have a scratch disk, which means you can't use an
f1-micro
or g1-small
to build images.