Packer: Building images on Google Cloud
ant Kenworthy
Posted on September 8, 2020
Installing the software we need to run our website or tools, can take some time to complete. This isn't ideal when our deployments are time sensitive, like when we need to scale up the web server pool to handle that sudden interest in your latest line of fancy socks.
We can solve this issue by pre-installing the software we need and setting the configuration options, which we can then turn in to an image we can deploy over and over again.
To make this entire process quicker, repeatable and something we can easily template - We'll use packer
What is Packer?
Packer is a Hashicorp tool that can be used to ease the creation of system images on cloud platforms or for other local tools like Vagrant ( another Hashicorp tool), Docker and VirtualBox.
Where can I get it ?
You can download the HashiCorp Packer tool from the download page on the packer website
There's also a handy guide on the hashicorp learning portal for how to install it on your operating system
How can I use it with the Google Cloud Platform?
You'll need to create a "builder" configuration in your packer file.
Here's a basic example:
{
"builders": [
{
"type": "googlecompute",
"project_id": "my project",
"zone": "us-central1-a",
"source_image_family": "debian-10",
"ssh_username": "packer",
"image_name": "packer-{{timestamp}}",
"image_family": "socks-web"
}
]
}
The options we have set above do the following things:
type
is the type of builder we're using. Here its googlecompute
because we're talking to GCP
project_id
is the project where the final image will be stored
zone
Will be the zone we build our image in
source_image_family
This is the group of images where our base image will be taken from
ssh_username
The ssh username we'll use to talk to the instance that will create our image
image_name
The name of the image we will create.
The image name needs to be unique within our project so we're using the packer variable timestamp
to do that.
image_family
The name of our image family. This is optional but is useful later on.
What is this image_family
thing ?
Images can be stored in groups referred to as image families. When building instances we can ask GCP to get our image from our family which will return the latest image that was added to it.
If something is found to be wrong with a new image we can tag it as deprecated and the family will offer up a previous version next time we deploy an instance.
More info on image families can be found in the GCP documentation
How do I install that web server in my image?
You'll need to add a provisioner or two, to your packer config file.
Provisioner's are usually shell scripts or file uploads but could be a puppet, ansible, salt or chef operation.
Here's a complete example of our packer file including our new provisioners:
{
"builders": [
{
"type": "googlecompute",
"project_id": "my project",
"zone": "us-central1-a",
"source_image_family": "debian-10",
"ssh_username": "packer",
"image_name": "packer-{{timestamp}}",
"image_family": "socks-web"
}
],
"provisioners": [
{
"type": "file",
"source": "./index.html",
"destination": "/tmp/index.html"
},
{
"type": "shell",
"inline": [
"sudo apt-get update -qq",
"sudo apt-get upgrade -qq",
"sudo apt-get install -qq apache2",
"sudo cp /tmp/index.html /var/www/html/index.html",
]
}]
}
Here we copy our index.html
file to /tmp
, Update the cache for apt, perform a system upgrade to make sure we have all the updates installed then install apache and finally copy our index page in to place.
How do I build that image ?
You can now run the following command from the directory where you've saved the packer file:
packer build example.json
Packer will now go away and build that image for you and will store the resulting image as packer-xxxxxxxxx
( where xxxxxxxxx
is a timestamped value ) The resulting image will be linked to the image family socks-web
which you will then be able to reference in your terraform template for your project.
🎉 Tada!
Are there other things to know ?
Yes, there are a couple of things:
Networking
The example above assumes the project you are using contains a default networking setup with subnetworks available in your chosen zone. If these things aren't available the build process will fail and you'll need to add a network
OR subnetwork
option to the builder config which lines up with your chosen zone.
It also assumes that the default firewall rules are in place so packer can ssh to the instance it creates.
If you don't have the needed firewall rules to allow access your build process will time out while waiting to connect.
machine_type
has been omitted from the example
It will default to n1-standard-1
but you may need to increase its size depending on what you're doing. A larger machine type will help it run faster.
Cost
There is a cost for storing your images.
At time of writing its about $0.050 for US and EU multi region storage but it can be as high as $0.075 is specific regions.
There will also be a cost for building the image.
This will vary based on the image size you use and where you choose to build it.
At time of writing the cost of the the given example should be in the region of $0.04749975 Per hour
Check the pricing page for more info.
To quote the pricing pages:
If you pay in a currency other than USD, the prices listed in your currency on Cloud Platform SKUs apply.
❗ Make sure you check the cost before you run up a big bill ❗
Cleaning up
If you don't want that image you've just created you can head over to images in the compute section of the console and delete the image you no longer want.
Note: You cannot delete public images from your project - They are free anyway 😃
Posted on September 8, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.