I’ve found that, though I like the pre-existing images on Googles Cloud- Compute Engine, I would like to make my own. Once you get a template system that is just the way you want it, you might decide that you would like to make more instances with an existing VM as a starting point. Depending on if you intent to share this image with others, or not, there are two ways to go about it.
NOTE: All of the Green code will need to be replaced with your relevant data!
First, The Easy Way!
The fastest and easiest way to do this is to take a snapshot and then create the instance from the snapshot. The only shortcoming with this method is that the snapshot cannot be shared with others.
Enter the Google Developers Console, and press the on the top right and select Compute Engine. Then select Snapshots from the right. At the top, select NEW SNAPSHOT. Name the snapshot, and select what disk you are taking a snapshot from.
CLI: This can also be done from the google cloud shell, (or your own computer if you have the gcloud SDK.)
gcloud compute --project "Project-Name" disks snapshot "disk-1" --zone "us-central1-b" --description "example snapshot" --snapshot-names "new-test-snapshot"
Once the snapshot has been created, click on the name of the snapshot in the list. Once again, at the top of the page there will be a link- CREATE INSTANCE.
Select the link and fill out the form to mount your snapshot in a new instance. Magic! Now you have two essentially identical instances
gcloud compute --project "Your-Project" disks create "Disk-Name" --size "10" --zone "us-central1-b" --source-snapshot "snapshot-name" --type "pd-standard"
gcloud compute –project “Your-Project” instances create “Instance-Name” –zone “us-central1-b” –machine-type “n1-standard-1” –network “default” –maintenance-policy “MIGRATE” –scopes “https://www.googleapis.com/auth/cloud.useraccounts.readonly”,”https://www.googleapis.com/auth/devstorage.read_only”,”https://www.googleapis.com/auth/logging.write”,”https://www.googleapis.com/auth/monitoring.write” –disk “name=Disk-Name” “device-name=Instance-Name” “mode=rw” “boot=yes” “auto-delete=no”
Now the Harder Way
The other way to go about this is a bit more difficult, but it allows you the option to store the image in it’s raw format, as well as add it to your list of images when you create a new instance. Not to mention- you can share this image easily without posting it publicly!
To start with, you need to have a non-root disk to store the image on.
gcloud compute disks create Disk-Name
GUI: In Google Developers Console, under Computer Engine (same place we were before creating the snapshot.) Select Disks from the left side of the page. Click NEW DISK at the top of the page and fill in the form. Note: Source type needs to be “None (blank disk)”
Next we need to attack the blank disk to your existing VM.
gcloud compute instances attach-disk Instance-Name --disk Disk-Name --device-name Disk-Name
GUI: Select VM Instances from the left menu. Click on the name of your instance in the list below the graph. Select Edit from the top menu. Scroll down to “Additional disks” and click + Add item. Select the disk from the combo box and make sure the mode is Read/write.
SSH into your VM and run the following command to confirm that the disk has been attached properly.
ls -l /dev/disk/by-id/google-*
Find the disk in the list that matches the name you just created. If you didn’t have any other disks attached, it’s probably /dev/sdb.
Create a new dir to mount the disk. Then mount it up.
sudo mkdir /mnt/tmp-img
sudo /usr/share/google/safe_format_and_mount -m "mkfs.ext4 -F" /dev/sdb /mnt/tmp-img
Now we create the image and store it on the attached drive.
sudo gcimagebundle -d /dev/sda -o /mnt/tmp-img/ --log_file=/tmp/img.log
You will see a file call “A-BIG-HEX.image.tar.gz” This is the raw data image that you created from your root disk on the existing VM.
EDIT: It may be worthwhile to name the image something informative, rather than leaving it as a huge hex.
sudo mv /mnt/tmp-img/A-BIG-HEX.image.tar.gz /mnt/tmp-img/NAME.image.tar.gz
Put it in a Bucket!
if you don’t already have a Google Storage Bucket, you can create one by typing:
gsutil mb gs://UNIQUE-BUCKET-NAME
You can then copy the image to your bucket:
gsutil -m cp /mnt/tmp-img/A-BIG-HEX.image.tar.gz gs://UNIQUE-BUCKET-NAME
Sharing is Caring.
Now that the image is in your bucket you can do two things- 1.)Import it into your console so that it shows up in the list of images when you create and instance, and 2.) share the image with other developers.
1.)Import the Image
This can be done easily with the GUI or with CLI.
GUI: Select Images under Compute Engine. Here you will see the pre-created list of images available. Select NEW IMAGE at the top of the screen. Fill out the form and select Cloud Storage file under source. Then click Browse on the right, and select the bucket that has your image, then select the image.
gcloud compute --project "Project-Name" images create "New-Image-Name" --source-uri https://storage.googleapis.com/UNIQUE-BUCKET-NAME/A-BIG-HEX.image.tar.gz
2.) Share that Bucket!
Go to the top right corner and press the again. Scroll down and select Storage. Click on the name of the bucket that stores your image you created. Click the three vertical dots to the right and select “Edit Permissions.” All you need to know is the email address of the developer you want to share with. Select + Add item. Under ENTITY select User. Under NAME: enter their email address. Under ACCESS you can chose between Reader and Owner. This is equivalent to read vs read/write. When finished press save. This will allow the listed user to go to their storage console, select transfer, then import the image.
Note- that can be tricky sometimes, and it might just be easier to send the image to them directly.
This can be done by, first having the recipient create a bucket, then add you as a writer under “Edit Permissions” Afterwards, do the transfer from your console under: Google Developers Console- Storage- Transfer.
Once the image has been received in the recipients bucket, the same process described above can be used to import the image and create a new instance.
EDIT: What if I don’t want to share my whole bucket… Is there another way?
Indeed there is, and honestly- it’s faster, as long as you are comfortable with command line. This method involves a google cloud shell terminal transfer of the image file directly from one bucket to another. The only thing you need to do is have the file permissions on the object itself shared with the recipient user. Go to the top right corner in the Compute Engine and click the [>_] icon to open the cloud shell. Then enter the following code:
gsutil -m cp gs://FROM-BUCKET-NAME/IMAGE-NAME.tar.gz gs://TO-BUCKET-NAME/IMAGE-NAME.tar.gz
This will be extremely quick if you have your perms set, and both buckets are on the same server. Once Transferred- follow the step 2.) above in the same cloud shell to import the image.