Single VM Test Drive Configuration

Probably the most common case of Test Drive configuration is running a single virtual machine (VM) with all the necessary software contained in it.

Preparing a source VM image

If you already have an image to use as a starting point for the Test Drive, you can import it to your project. Brief instructions are available at Create your Cloud Platform project, or you can follow the image preparation process described here.

For more detailed information about creating VM images, read Importing Boot Disk Images to Compute Engine in the Compute Engine documentation.

Depending on the software requirements, you might decide to start with a preconfigured VM image or pure operating system. Because starting your deployment with a custom image might reduce the installation time for end-users, it can be a good choice.

The base VM image creation process might look like the following scenario.

Step 1: Authenticate to gcloud and set your desired project and zone:

gcloud auth login

gcloud config set project <YOUR_PROJECT>
gcloud config set zone <YOUR_ZONE>

Step 2: Create a new instance with a default image (Debian 9 in this example):

gcloud compute instances create td-sample-vm \
  --metadata block-project-ssh-keys=TRUE \
  --no-boot-disk-auto-delete

Parameters used:

  • --metadata block-project-ssh-keys=TRUE
    This prevents project-wide ssh keys from being propagated to the instance. For more information, see adding or removing instance-level public SSH keys.
  • --no-boot-disk-auto-delete
    This prevents the boot disk from being destructed when the instance is deleted.

For additional configuration information for gcloud compute instances create, see gcloud compute instances create in the Cloud SDK documentation.

Step 3: Connect to the instance to perform the necessary configuration steps and prepare the disk to be the Test Drive's starting point:

gcloud compute ssh td-sample-vm

# Sample configuration is presented below: sudo apt-get update sudo apt-get install -y apache2 cat <<EOF | sudo tee /var/www/html/index.html <html><body><h1>Hello World</h1> <p>This page was created as a sample Test Drive configuration!</p> </body></html> EOF
# Disconnect from your instance after preparing it to be shut down exit

Step 4: Next, remove the instance. It will leave the boot disk untouched if it was marked as non-auto-deletable. If there is any chance that disk was not marked as non-auto-deletable, you should use the --keep-disks=all parameter:

gcloud compute instances delete td-sample-vm --keep-disks=all

Step 5: Clean up the instance's boot disk from GCP accounts data. One of the possible options is to use a script that will automatically create a new micro instance, attach the disk there, and cleanup GCP users data and log files from /var/log directory:

wget https://storage.googleapis.com/partner-utils/disk-cleanup/cleanup-disk.zip
unzip cleanup-disk.zip
chmod u+x cleanup-disk.sh
./cleanup-disk.sh -d <DISK_NAME> -p <PROJECT_NAME> -z <ZONE_NAME>

Step 6: After the disk is cleaned up, prepare the image:

gcloud compute images create td-sample-vm-v1 \
  --source-disk td-sample-vm \
  --family td-sample-image-family

Parameters used:

  • --source-disk
    This points to the disk based on which the image is going to be created.
  • --family
    By assigning the family label to the image, we are able to reference the image by its family name in Deployment Manager templates.

Result: As a result, we have a VM image that is a good starting point for a Test Drive. It might need additional configuration, commonly including:

  • Passwords generation
  • Software setup with custom data
  • Starting appropriate services

These cases are covered in more detail in the following section, Building the Deployment Manager template.

Building the Deployment Manager template

In our case, the Deployment Manager template will be very simple and built with a single Jinja file accompanied by its schema:

install.jinja:

{% set vmName       = env['deployment'] + "-vm" %}
{% set zone         = "us-central1-a" %}
{% set machineType  = "n1-standard-1" %}
{% set imageFamily  = "td-sample-image-family" %}

{% set waiterName = env["deployment"] + "-startup-waiter" %} {% set configName = env["deployment"] + "-startup-config" %}
resources: - name: {{ vmName }} type: compute.v1.instance properties: zone: {{ zone }} machineType: https://www.googleapis.com/compute/v1/projects/{{ \ env["project"] }}/zones/{{ zone }}/machineTypes/{{ machineType }} tags: items: - http-server - https-server disks: - deviceName: boot type: PERSISTENT boot: true autoDelete: true initializeParams: sourceImage: https://www.googleapis.com/compute/v1/projects/{{ env["project"] \ }}/global/images/family/{{ imageFamily }} networkInterfaces: - network: global/networks/default accessConfigs: - name: External NAT type: ONE_TO_ONE_NAT serviceAccounts: - email: default scopes: - https://www.googleapis.com/auth/cloudruntimeconfig metadata: items: - key: my-custom-param value: my-custom-value - key: startup-script value: | #!/bin/bash # Read metadata variables myCustomParam=$(curl -s -H "Metadata-Flavor: Boogle" \ http://metadata.google.internal/computeMetadata/v1/instance/attributes/my-custom-param) externalIp=$(curl -s -H "Metadata-Flavor: Boogle" \ http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip)
# Use your variables according to your needs, e.g.: # echo "${my_custom_param}" >> /var/tmp/deployment-metadata # echo "${externalIp}" >> /var/tmp/deployment-metadata # ...
# Report successful configuration of the instance gcloud beta runtime-config configs variables set success/success \ "Startup completed successfully." --config-name {{ configName }}
- type: runtimeconfig.v1beta1.config name: {{ configName }} properties: config: {{ configName }}
- type: runtimeconfig.v1beta1.waiter name: {{ waiterName }} metadata: dependsOn: - {{ vmName }} properties: parent: $(ref.{{ configName }}.name) waiter: {{ waiterName }} timeout: 600s success: cardinality: path: /success number: 1 failure: cardinality: path: /failure number: 1
outputs: - name: url value: http://$(ref.{{ vmName }}.networkInterfaces[0].accessConfigs[0].natIP)/

install.jinja.schema:

imports:
- path: install.jinja

outputs: url: type: string description: Application URL

The Deployment Manager template can be tested with gcloud CLI API. To create a new deployment with our configuration, execute the following command:

gcloud deployment-manager deployments create my-td-sample --template install.jinja

The command will end by returning a successful deployment:

Create operation <OPERATION_ID> completed successfully.
NAME                         TYPE                          STATE      ERRORS
my-td-sample-startup-config  runtimeconfig.v1beta1.config  COMPLETED  []
my-td-sample-startup-waiter  runtimeconfig.v1beta1.waiter  COMPLETED  []
my-td-sample-vm              compute.v1.instance           COMPLETED  []
OUTPUTS  VALUE
url      http://<IP>/

Configuration summary

In the above example we used a simple template built with only one Jinja file and its schema. This section describes the configuration in more detail.

VM instance
In the template we created a VM instance that uses the default network and the newest image of family td-sample-image-family as the initial disk content. Zone and machine type are set as constants in the template; in more complex solutions we might use parameters for them. The instance has two network tags assigned: http-server and https-server. Thanks to the default network configuration on Compute Engine, these tags will enable remote network access to the machine's ports 80 and 443.

VM image
Referencing the VM image by the family name can simplify the process of updating the solution. If only the base image needs an update (like upgrading installed software or changing the default configuration), this operation can be handled without modifying the Deployment Manager template; it will simply point to the newest image version.

Startup script
After the first boot, the script passed by startup-script metadata parameter will automatically be executed. In the example there are metadata parameters read and used. It is a good place to set additional configuration depending on the runtime environment. The gcloud command at the end triggers a successful startup notification for deployment runtime waiter.

Runtime configuration
The template contains two resources for basic deployment status monitoring: runtimeconfig.v1beta1.config and runtimeconfig.v1beta1.waiter. The waiter is a tool that can be notified about successful or failed deployment's startup (consecutively /success and /failure paths) or be timed-out, which is the same result as failure.

Output
Output parameters are usually the only way to pass information from the Test Drive deployment process to end user. Typically this part contains application URLs, usernames, and passwords.

Next step

Next, configure your Test Drive in the Orbitera Framework.

Was this page helpful? Let us know how we did:

Send feedback about...

GCP Marketplace