Windows
To create a Windows VM on Google Cloud, you must use a VM image that has Windows
or Windows Server preinstalled. Google Cloud provides
public images
for commonly used versions of Windows Server, but these images are only suitable for
on-demand licensing
.
To bring your own Windows license (BYOL), you must either
import an existing image
, or you must build a custom image.
This guide describes how you can create a custom image by using the same tools
and processes that Google Cloud uses to create the public images.
To complete this guide, you need:
- An ISO file containing the Windows or Windows Server installation media.
- Optionally, one or more Windows update packages (in
.msu
format) to apply to the image.
Before you begin
Understand the build process
To install Windows from scratch, a common approach is to boot a computer from
a DVD or ISO file that contains the Windows installation files. Unlike some on-premises
hypervisors, Compute Engine does not let you boot from an ISO file.
To install Windows from scratch, you must therefore follow a different approach
that entails the following steps:
- Creating a new disk.
- Extracting the Windows image (
install.wim
from the installation media) to the disk.
- Adding necessary drivers, configuring Windows Setup so that it runs unattended, and making the disk bootable.
- Booting from the new disk to run Windows Setup.
- Installing additional software including the Guest OS agent.
- Creating an image from the disk.
Instead of performing these steps manually, this guide describes how you can use
Cloud Build
, the
daisy
tool, and the reference workflows which are
available on GitHub
to automate the process.
daisy
is an
open source command-line tool
that lets you execute workflows. Workflows are authored as JSON files and contain
a sequence of steps. Each such step describes a Compute Engine operation ? for
example, creating a disk, or shutting down a VM instance. Daisy workflows are
therefore suitable to automate the steps required to build a Windows image from scratch.
The daisy workflows for building custom Windows images create two temporary VM instances.
The first VM instance (prefixed
bootstrap
) performs the necessary steps to create
a bootable disk. The second VM instance (prefixed
install
) runs Windows Setup
and performs all the remaining steps.
Prepare the project for building images
To prevent the daisy tool from interfering with your existing VM instances or
infrastructure, create a dedicated project for building images:
-
Sign in to your Google Cloud account. If you're new to
Google Cloud,
create an account
to evaluate how our products perform in
real-world scenarios. New customers also get $300 in free credits to
run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page,
select or
create a Google Cloud project
.
Go to project selector
-
Make sure that billing is enabled for your Google Cloud project
.
-
Enable the Compute Engine API, Cloud Build API, and Cloud Storage API APIs.
Enable the APIs
-
In the Google Cloud console, on the project selector page,
select or
create a Google Cloud project
.
Go to project selector
-
Make sure that billing is enabled for your Google Cloud project
.
-
Enable the Compute Engine API, Cloud Build API, and Cloud Storage API APIs.
Enable the APIs
The next steps differ depending on whether you use Windows or Linux on your local computer:
Windows
- On your local computer, open a Windows PowerShell window.
Initialize a variable:
$PROJECT_ID = "
PROJECT_ID
"
where
PROJECT_ID
is the project ID of the
Google Cloud project that you created in the previous section.
Initialize another variable so that it contains the project number of the project:
$PROJECT_NUMBER = gcloud projects describe $PROJECT_ID --format=value`(projectNumber`)
Linux
- On your local computer, open a terminal window.
Initialize a variable:
PROJECT_ID=
PROJECT_ID
where
PROJECT_ID
is the project ID of the
Google Cloud project that you created in the previous section.
Initialize another variable so that it contains the project number of the project:
PROJECT_NUMBER=`gcloud projects describe $PROJECT_ID --format=value\(projectNumber\)`
Upload installation files
You now collect all the installation files required for the custom image and upload
them to a Cloud Storage bucket. By storing the files in a Cloud Storage bucket,
you ensure that the files are accessible by
daisy
and by the temporary VM instances
that
daisy
uses to build the image.
On your local computer, download required installation packages:
Create a new Cloud Storage bucket to store the installation files:
gsutil mb -p $PROJECT_ID gs://$PROJECT_ID-media
Grant the
Storage Object Viewer
role to Cloud Build so that it can read the installation files:
gsutil iam ch serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com:objectViewer gs://$PROJECT_ID-media
Upload the PowerShell installation package:
gsutil cp
POWERSHELL_PACKAGE
gs://$PROJECT_ID-media/PowerShell.msi
where
POWERSHELL_PACKAGE
is the path to the PowerShell
installation package.
Upload the .NET Framework installation package:
gsutil cp
DOTNET_PACKAGE
gs://$PROJECT_ID-media/dotnet-sdk.exe
where
DOTNET_PACKAGE
is the path to the NET Framework
installation package.
Upload the gcloud CLI installation package:
gsutil cp
CLOUDSDK_PACKAGE
gs://$PROJECT_ID-media/GoogleCloudSDKInstaller.exe
where
CLOUDSDK_PACKAGE
is the path to the gcloud CLI
installation package.
Upload the ISO file containing your Windows installation media:
gsutil cp
ISO
gs://$PROJECT_ID-media/
where
ISO
is the name of the ISO file.
Optionally, upload additional update packages:
gsutil cp
UPDATE_DIR
/*.msu gs://$PROJECT_ID-media/updates/
where
UPDATE_DIR
is the directory containing the update packages.
You are now ready to build the custom image.
Build the image
Executing the
daisy
workflow to build a custom image takes up to four hours.
Instead of running
daisy
locally, you now create a Cloud Build configuration
so that you can let Cloud Build execute the workflow in the background.
On your local computer, clone the Git repository containing the
daisy
workflows
for building Windows images:
git clone https://github.com/GoogleCloudPlatform/compute-image-tools.git
Switch to
windows
directory:
cd compute-image-tools/daisy_workflows/image_build/windows/
In the
windows
directory, you find a selection of files with the suffix
.wf.json
. These files contain Daisy workflow definitions for commonly used
Windows versions:
Windows version
|
Workflow file
|
Windows Server Core 2022 (64-bit)
|
windows-server-2022-dc-core-uefi-byol.wf.json
|
Windows Server 2019 (64-bit)
|
windows-server-2019-dc-uefi-byol.wf.json
|
Windows Server Core 2019 (64-bit)
|
windows-server-2019-dc-core-uefi-byol.wf.json
|
Windows Server 2016 (64-bit)
|
windows-server-2016-dc-uefi-byol.wf.json
|
Windows Server Core 2016 (64-bit)
|
windows-server-2016-dc-core-uefi-byol.wf.json
|
Windows 11 21H2 (64-bit)
|
windows-11-21h2-ent-x64-uefi.wf.json
|
Windows 11 22H2 (64-bit)
|
windows-11-22h2-ent-x64-uefi.wf.json
|
Windows 11 23H2 (64-bit)
|
windows-11-23h2-ent-x64-uefi.wf.json
|
Windows 10 21H2 (64-bit)
|
windows-10-21h2-ent-x64-uefi.wf.json
|
Windows 10 22H2 (64-bit)
|
windows-10-22h2-ent-x64-uefi.wf.json
|
Open the workflow file that most closely matches the Windows version that
you want to install. If necessary, change the Windows edition (
edition
) and
license key (
product_key
) settings in the workflow files so that they match
your installation media.
If you are unsure about the correct edition name, open an elevated PowerShell
prompt and run the following commands to list all editions supported by your
installation media:
$IsoFile = "
ISO
"
$Mount = Mount-DiskImage -ImagePath (Resolve-Path $IsoFile)
$DriveLetter = ($Mount | Get-Volume).DriveLetter
Get-WindowsImage -ImagePath "$($DriveLetter):\sources\install.wim" | select ImageName
Dismount-DiskImage -InputObject $Mount | Out-Null
Replace
ISO
with the local path to the ISO image.
In the
windows
directory, create a new file named
cloudbuild.yaml
and paste
the following code:
timeout: 14400s # 4 hour timeout for entire build
steps:
- name: 'gcr.io/compute-image-tools/daisy'
timeout: 14400s # 4 hour timeout for build step
waitFor: ['-']
args:
- -project=$PROJECT_ID
- -zone=us-central1-a
- -var:updates=gs://$PROJECT_ID-media/updates/
- -var:pwsh=gs://$PROJECT_ID-media/PowerShell.msi
- -var:dotnet48=gs://$PROJECT_ID-media/dotnet-sdk.exe
- -var:cloudsdk=gs://$PROJECT_ID-media/GoogleCloudSDKInstaller.exe
- -var:media=gs://$PROJECT_ID-media/
ISO
-
WORKFLOW
Replace:
ISO
: name of the ISO file on Cloud Storage.
WORKFLOW
: name of the workflow file that corresponds
to the Windows version that you're using.
Submit the build to Cloud Build:
gcloud builds submit --project $PROJECT_ID --async
The build takes around up to four hours to complete. You can track the status of the
build in the Google Cloud console under
Cloud Build > History
.
Cloud Build History
Use the custom image
After the build has completed, you can find the custom BYOL image in the
Google Cloud console under
Compute Engine > Images
.
To help differentiate between multiple versions of the same image, the build
process embeds a timestamp into the image name, for example
windows-server-2019-dc-v1613488342
.
In addition, the process associates the image with a custom
image family
,
for example
windows-server-2019
.
To create a VM instance that uses the custom BYOL image, you must
provision the VM instance on a sole-tenant node
.
Troubleshooting
If you suspect that the build process failed or is not progressing, use the
following approaches to diagnose the situation:
- Verify that you've uploaded the right installation packages and ISO file.
- Verify that you selected a workflow that matches the Windows version of the ISO file.
- Review the
build log in Cloud Build
and check whether there are any error messages.
- If the build seems stuck, review the
serial port output
of the VM instance created by the build and check for error messages.
What's next