The CloudBase-provided image is built using a set of scripts and
configuration files that CloudBase has made available on
GitHub.

The CloudBase repository is an excellent source of information, but I
wanted to understand the process myself. This post describes the
process I went through to establish an automated process for
generating a Windows image suitable for use with OpenStack.

Unattended windows installs

The Windows installer supports fully automated installations through
the use of an answer file, or “unattend” file, that provides
information to the installer that would otherwise be provided
manually. The installer will look in a number of places to find
this file. For our purposes, the important fact is that the installer
will look for a file named autounattend.xml in the root of all
available read/write or read-only media. We’ll take advantage of this
by creating a file config/autounattend.xml, and then generating an
ISO image like this:

mkisofs -J -r -o config.iso config

And we’ll attach this ISO to a vm later on in order to provide the
answer file to the installer.

So, what goes into this answer file?

The answer file is an XML document enclosed in an
<unattend>..</unattend> element. In order to provide all the
expected XML namespaces that may be used in the document, you would
typically start with something like this:

windowsPE – used to install device drivers for use within the
installer environment. We will use this to install the VirtIO
drivers necessary to make VirtIO devices visible to the Windows
installer.

specialize – In this pass, the installer applies machine-specific
configuration. This is typically used to configure networking,
locale settings, and most other things.

oobeSystem – In this pass, the installer configures things that
happen at first boot. We use this to step to install some
additional software and run sysprep in order to prepare the
image for use in OpenStack.

Inside each <settings> element we will place one or more
<component> elements that will apply specific pieces of
configuration. For example, the following <component> configures
language and keyboard settings in the installer:

Cloud-init for Windows

Cloud-init is a tool that will configure a virtual instance when
it first boots, using metadata provided by the cloud service provider.
For example, when booting a Linux instance under OpenStack,
cloud-init will contact the OpenStack metadata service at
http://169.254.169.254/ in order to retrieve things like the system
hostname, SSH keys, and so forth.

While cloud-init has support for Linux and BSD, it does not support
Windows. The folks at Cloudbase have produced cloudbase-init
in order to fill this gap. Once installed, the cloudbase-init tool
will, upon first booting a system:

Configure the network using information provided in the cloud
metadata

Passwords and ssh keys

While cloudbase-init will install your SSH public key (by default
into /Users/admin/.ssh/authorized_keys), Windows does not ship with
an SSH server and cloudbase-init does not install one. So what is it
doing with the public key?

While you could arrange to install an ssh server that would make use
of the key, cloudbase-init uses it for a completely unrelated
purpose: encrypting the randomly generated password. This encrypted
password is then passed back to OpenStack, where you can retrieve it
using the nova get-password command, and decrypt it using the
corresponding SSH private key.

Providing your secret key as an additional parameter will decrypt the
password:

$ nova get-password myinstance ~/.ssh/id_rsa
fjgJmUB7fXF6wo

With an appropriately configured image, you could connect using an RDP
client and log in as the “Admin” user using that password.

Passwords without ssh keys

If you do not provide your instance with an SSH key you will not be
able to retrieve the randomly generated password. However, if you can
get console access to your instance (e.g., via the Horizon dashboard),
you can log in as the “Administrator” user, at which point you will be
prompted to set an initial password for that account.

Logging

You can find logs for cloudbase-init in c:\program files
(x86)\cloudbase solutions\cloudbase-init\log\cloudbase-init.log.

If appropriately configured, cloudbase-init will also log to the
virtual serial port. This log is available in OpenStack by running
nova console-log <instance>. For example:

Where TARGET_IMAGE is the name of a pre-existing qcow2 image onto
which we will install Windows, WINDOWS_IMAGE is the path to an ISO
containing Windows Server 2012r2, VIRTIO_IMAGE is the path to an ISO
containing VirtIO drivers for Windows (available from the Fedora
project), and CONFIG_IMAGE is a path to the ISO containing our
autounattend.xml file.

Troubleshooting

If you run into problems with an unattended Windows installation:

During the first stage of the installer, you can look in the
x:\windows\panther directory for setupact.log and setuperr.log,
which will have information about the early install process. The x:
drive is temporary, and files here will be discarded when the system
reboots.

Subsequent installer stages will log to
c:\windows\panther\.

If you are unfamiliar with Windows, the type command can be used
very much like the cat command on Linux, and the more command
provides paging as you would expect. The notepad command will open
a GUI text editor/viewer.

You can emulate the tail command using powershell; to see the last
10 lines of a file: