Automated, Static, re-ip of GCP Windows VM
By: Barry Searle
Tags: Disaster Recovery, Gcp, Windows, Networking

Problem statement

Let’s set the scene here. You have an instance that has been configured to use a static IP address in a GCP region. Your DR strategy is to create an image of the instance in the production region and restore it in the DR region. Production and DR subnets are different.

When you come to create an instance from this image, during simulation of a DR event (hopefully it’s a simulation) you find that to your horror, the instance cannot communicate on the network, since it is set to the original static ip address which is outside of the range of the subnet on which it has been restored.

There are many topics this raises that I will not go into in any depth here.

Please use DHCP so the Cloud platform can take over the allocation of IP addresses, even “static” ones. Is creating an image the appropriate backup methodology?

How do we solve this?

instances on GCP have a “Guest Environment”. These are installed by default on all of the Google-provided public images. The guest environment is a set of scripts, daemons, and binaries that read the content of the metadata server to make a VM run properly on Compute Engine. A metadata server is a communication channel for transferring information from a client to the guest operating system.

Here is a link to more information about the Guest Environment. We are going to use the metadata server extensively to pass required metrics into the VM to facilitate the process of switching to a new static IP address.

You can dig deeper into the code if you like. Here is a link to the github repo that contains the windows code which is mainly in powershell. It contains callable functions that you can leverage for accessing the windows registry, the file system and GCP libraries such as the Runtime Configurator. The Runtime Configurator is also a topic for a different article, but it helps you synchronize the deployment of your environment, so that all dependencies are in place as the next wave of infrastructure is being created.

Back to the task at hand. How does any of this help us deploy an instance with a new static IP? GCP allows for startup scripts to be run, when a machine starts up, documented very nicely here. They can be provided in the cloud console, gcloud command-line tool or the REST API.

They can be passed in:

Directly As a path to a file in Google Cloud Storage As a path to a local file

Here is a table explaining the when and how:

Use Powershell for its richness, and you need it to run after sysprep completes, so the metadata key that will be entered to identify the script is windows-startup-script-ps1. This will point to a local Powershell file, that will be executed as elevated administrator on the first boot. It would run on every subsequent boot so you need to remove it from the metadata server after the first and only execution.

Getting parameters to the script

To set up the instance with a new IP address you need to provide the following:

IPAddress

Gateway

To pass them into the script that will run as admin on startup, put them in metadata.

Adding metadata to the instance

Explanation of the gcloud command

We are using gcloud beta, so we can create an instance directly from a machine image

We are passing in the IP and gateway

The metadata-from-file parameter is looking for a local file on the instance on which you are running gcloud. The path can be relative to where your working directory.

Note: You can also add any random metadata to a running instance using the following command:

This is not covered in this article, but you could add the script to a running instance, reboot, and it would change its ip address.

Accessing Instance Metadata from the Script

You need to get the metadata for “ipaddr” and “gateway” out in the script “windows-set-static.ps1”.

The commands to get these values out of metadata in the powershell script are as follows :

Note: 169.254.169.254 is the address of the local metadata server that is installed with the guest environment.

The command to remove the script from the instance metadata is (done at the end to prevent subsequent execution:

The Powershell Script

The script can be found here: link

The instance starts up with the original ip address, on a subnet on which it cannot communicate. To fix this you need to:

Enable DHCP so it refreshes the NIC with a local IP address and Gateway

Set the Adapter back to static

Add the new network address with the new ip address and gateway

Set the new gateway to also be the DNS Server address (You could pass this in as another piece of metadata)

The commands in Powershell to achieve these goals are:

Set-NetIPInterface

New-NetIPAddress

Get-NetRoute

Remove-NetRoute

Set-DNSClientServerAddress

This has shown itself to be a good approach in my environment, but in yours, many things could be different and as such this article does not claim to be a definitive solution to the problem. It outlines one possible approach that has worked for me.