Using Packer to Build Server Images with Google Cloud Build
Start course

Learn how to simplify all of your application infrastructure into just a few configuration files then deploy your code on Google Cloud Platform with this course. We will start by learning the core concepts behind Infrastructure as Code, discussing security best practices when working with IaC, and comparing some popular orchestration and configuration management tools.

After that, we’ll implement version control for our IaC configurations, and learn how we can automate deployment updates using Cloud Build Triggers. Next, we’ll learn how to integrate Google Secret Manager to protect any sensitive data in our source code. Then to tie it all together, we’ll walk through Google Identity and Access Management and learn how to monitor our users and resources on GCP.

After learning the basics, we’ll build our own immutable server images with Google Cloud Build using both Docker and Packer. We’ll then explore a practical usage scenario and build a WordPress deployment with Google Deployment Manager. We’ll also deploy a similar WordPress configuration using Terraform to compare the two methods.

I will be working in Visual Studio Code during the demos for this course, but you are also free to use any other IDE you are comfortable with instead. A demo repository is provided along with this course, and while we will be working with some Python and PHP in our examples, you should still be able to follow along with the demos without any background in either of these languages.

Learning Objectives

  • Build server images from a configuration file using Docker and Packer.
  • Learn to use Google Cloud Build with third-party build steps.
  • Deploy application infrastructure from code using Google Deployment Manager and Terraform.
  • Understand templating systems for Infrastructure as Code.
  • Implement version control for Infrastructure as Code.
  • Learn to protect secret data in IaC configurations using Google IAM role management and Google Secret Manager.

Intended Audience

This course is intended for programmers interested in expanding their knowledge about modern cloud-based DevOps workflows. Learning to manage Infrastructure as Code is beneficial to solo developers who need to focus as much of their time as possible on their application code and not on managing infrastructure. Development teams will also benefit from this course, because implementing IaC provides consistent performance across deployments in multiple environments, which greatly simplifies project collaboration. This course will also help prepare the viewer for the Google Professional Cloud DevOps Engineer certification.


  • You should already have a Google Cloud Platform account.
  • You should have Google Cloud SDK already installed and initialized.
  • You should already have Git installed, and be familiar with its use.
  • Demos will be shown in Visual Studio Code, but you're free to use any IDE they are familiar with.
  • Demos will utilize some Python and PHP, but you're not required to be fluent in either of these languages to follow along with the examples.


Additional Documentation


Using Packer to Build Server Images with Google Cloud Build. One of the big benefits of Infrastructure as Code is portability. We can build many different kinds of servers across many different platforms using the same or similar configuration files.

While this course is focused on deploying Infrastructure as Code on GCP, the very tenants of Infrastructure as Code encourage us to avoid vendor lock-in. We don't want our application's functionality to rely upon any single provider in some way, this is in its own way a potential point of failure in our code. So, while we will be covering many products and services specific to Google Cloud Platform, we'll also be working with some cross-platform tools in our GCP deployment examples that can easily translate to other environments or platforms.

One tool that can help us build and deploy server images across multiple platforms is Packer from HashiCorp. With Packer we can build Docker container images using more advanced scripting than is possible in a Dockerfile. We can even integrate with a configuration management tool like Ansible, Chef, or Puppet in our Packer configuration. These tools connect to a temporary machine instance to make their changes, then our Docker image is created and the temporary instance is deleted when they are done. This way we still end up with an immutable server image, but we were able to build it using tools normally intended for managing mutable server deployments.

To build containers with Packer requires both Packer and Docker to be installed locally. Since we're working with Google Cloud Build, and we aren't using a configuration management tool in our deployment, using Packer to build the exact same container image represents a lot of extra work in our scenario. Instead we'll learn how to work with Google Cloud Build community images to use Packer with Cloud Build in a more typical usage scenario on GCP to build a Google Compute Engine image. In this way, we can adopt an immutable server administration approach even when working with GCE virtual machines, by treating them much like Docker containers and baking our changes into the image itself before deployment.

Unfortunately Packer for some reason doesn't have a convenient hub for ready made configurations the same way that Docker does. While we were able to build our Docker container off of a base image that already had WordPress, PHP, Apache, and Debian configured for us, with Packer we'll need to start with a base GCE Debian image and add all those layers of commands on top ourselves to build our WordPress server. This example will be rudimentary by comparison as a result, and we'll be relying on the container image we created in the previous lecture instead for the rest of this course.

This demo will still give you a good understanding of how you can treat GCE virtual machine instances as immutable architecture though, and shows how you can leverage Infrastructure as Code in traditionally mutable server environments. There are three files in our demo repository that we'll be using with Packer. Instead of a Dockerfile to define our server image, we have a packer.json file this time. I've created a variables section at the top to help make it easier to edit the configuration. You should change the region and zone here to match your project. The builders section tells Packer what platform we are building an image for. Packer supports builders for a long list of different providers, but as you might expect we're going to focus on Google Compute.

The provisioners section of our JSON file tells Packer what actions to run on the base image we just built in the builders section. Here is where we could hook in our configuration management system if we were using one. Using the shell type provisioner, we can execute a Bash script from our repository, which you can see just contains some quick and dirty commands to create a WordPress server on our fresh Debian image. We can also use the file type provisioner to include any files from our repository into our new image. Then we need a cloudbuild.yaml file just like we had in our Docker example, but with some added information to tell Cloud Build to use the Packer build step with our packer.json file.

Next, we need to make sure a few additional APIs are enabled. We can do this with some gcloud commands like we did earlier to save time here. We also need to make sure our Cloud Build service account has the editor role on our project. Remember Packer is not supported by Cloud Build natively, so next we need to add the Packer build step to our project for Cloud Build to use. We can do this by cloning the Cloud Build community builders repository, navigating to the Packer folder, and running the build command.

Now, if we navigate back to our repository, we are ready to run the build command on our Packer files. We can check the Cloud Console and see our build command running. When it's finished, we'll find a Google Compute Engine virtual machine image now waiting for us to use. When creating a new virtual machine instance on this project, we now have the option to use our new image as the boot disk for the server.

Don't forget that there are costs associated with running Cloud Build. There are many other community-contributed cloud builders that can be implemented in exactly the same way as Packer, so feel free to explore some of the other tools in the repository that you can use to help automate your builds.

About the Author

Arthur spent seven years managing the IT infrastructure for a large entertainment complex in Arizona where he oversaw all network and server equipment and updated many on-premise systems to cloud-based solutions with Google Cloud Platform. Arthur is also a PHP and Python developer who specializes in database and API integrations. He has written several WordPress plugins, created an SDK for the Infusionsoft API, and built a custom digital signage management system powered by Raspberry Pis. Most recently, Arthur has been building Discord bots and attempting to teach a Python AI program how to compose music.