Image building in practice
This is the practical guide on how to build images using the avdcli. Of course, there are a million other ways to build images that would work with Schoolyear AVD. However, by sticking to this guide, you can leverage all the experience and resources of the wider Schoolyear AVD community.
Installing avdcli
To get started with this guide, you need to download the avdcli
tool.
You can download the latest version from here.
We recommend you renaming the binary to avdcli
and putting in your PATH.
The rest of this guide assumes you have the avdcli
command available in your terminal.
Download avdcli
Running on MacOS
The pre-built binary on the release page of avdcli
is not notarized.
So when you try to run it, MacOS will refuse.
Follow these steps to whitelist the avdcli
on your machine:
-
Download the binary and rename it to
avdcli
. -
Allow execution of the binary by running
chmod +x avdcli
. -
Execute the downloaded
avdcli
from your commandline or by double clicking it. MacOS will show a popup prompting you to delete the file. Do not delete the file but dismiss the popup (“Done”). -
Open System Preferences and navigate to Privacy & Security.
-
Scroll down to Security and click Open Anyway.
-
Execute the binary from your commandline again. MacOS will show a popup, click “Open Anyway”.
Deployment repository
Many essential, pre-built scripts can be found in the Schoolyear AVD community. This guide will heavily rely on the scripts from this community as it contains all the scripts and configuration you need to build a clean base image.
We recommend you to fork this repository and check it out locally in a project folder on your local machine. The rest of this guide assumes you are working from within this directory.
To get up-and-running quickly, you can also download the repository directly from the website without using the Git toolchain. However, we do suggest making use of the Git toolchain once moving to a long-running production setting.
Schoolyear AVD community
So how is this going to work?
High-level overview of the process of making a new image available in your Schoolyear tenant:
-
Develop layers for each application that should be part of the exam environment. For some commonly used applications there might already be a pre-built layer available.
-
Combine the desired layers in an Image Package using
avdcli image package
. -
Build the exam image using
avdcli package deploy
. -
Create a new deployment template in Azure.
-
Publish a new Secure App in your Schoolyear tenant.
-
Test if the new App works before use in an exam.
Layers?
We are going to package each application we want to use in the image in what we call a layer.
Then we use avdcli
to combine these layers and build an image out of them.
The method to image building described in this guide focuses on building “exam-ready” images. We want the images used in exams to be static and fast to start up. Furthermore, we want to limit the reliance on network services, so we can isolate the exam network as much as possible. This means baking all the software and its configuration in the image itself and not relying on dynamic packaging tools.
To give an example, for one exam we want to set up an exam environment with both Office 365 and R-studio.
You would create a layer for Office and a layer for R-Studio.
Then you would use avdcli
to combine these layers and build the image for the exam.
Implementing a new layer
You can develop a layer for each application you want to package into an image. These layers should be developed to work independently so they can be reused in multiple images. For example, if you want to build an image with Office and R-Studio, you should make a layer for each of those applications. Those two layers should be developed in such a way that you can then later reuse the R-Studio layer to build an image with R-Studio and Python for example.
You can follow these steps to implement your own layer. The R-studio image is used as an example.
1. Create a new layer folder
Navigate to your avd-deployments folder you downloaded in a previous step and create a new image layer:
This will create a new folder rstudio
in the images
directory.
To conform to the existing folder structure of the avd-deployment
project,
we recommend you to put your image layers in this folder.
The rest of these steps are performed in this ./images/rstudio
folder:
2. Configure build steps
Now that we have a new image layer to work on, we’ll start by implementing the build steps. These are the steps that are executed during the image building process before the image snapshot is created. This would be the stage in which you want to run software installers and alike.
Avdcli is built on top of Azure Image Builder.
Azure Image Builder works by configuring a list of steps that should be executed on a VM before
an image snapshot is created.
Azure Image Builder will then execute these steps automatically.
You can configure these steps in the build_steps.json5
file in the root directory of the image layer.
The idea is that you put the scripts you need for image building in the resources
folder,
and then configure these scripts to be executed in the build_steps.json5
file.
To make sure your resources do not conflict with those of other layers,
the convention is to create a subfolder in the resources
directory with the name of the layer.
If your layer called “rstudio” (./images/rstudio
),
you would put your resources in the ./images/rstudio/resources/rstudio
folder.
The build_steps.json5
file is divided into three sections to give you some control over the order of execution
when combined with other layers.
Each build step has a name
and a type
property and possibly some extra properties specific to the type
.
The schema for these build steps is described in the
Azure Image Builder documentation.
Be wary of using the “Window Reboot” and “Windows Update” build steps, as they can easily add 10-20 minutes to the image building process, and most installations do not need it.
Installing an MSI/EXE
Most software you may want to package can be installed using an .msi
or .exe
installer.
This section gives you a starter template to get going.
First, create the installation script in a subfolder of the resources
directory.
For example, if your layer is called rstudio
, the file path would be images/rstudio/resources/install.ps1
.
Once you create the installation script, you can reference it in the build steps:
3. Network configuration
For most applications, you can skip this step. However, some applications require an HTTP(S) connection to a publicly hosted service. The most common use-case for this is public software-activation servers.
You can add a list of whitelisted host:port
combinations in the layer’s properties.json
file.
You can use the *
symbol as a wildcard.
Note that this only works for HTTP(S) services, not for general TCP/UDP connections. You can read more about how the whitelisting of these connections works here.
4. Setup scripts
The build scripts and steps you added in the previous step will be executed during the image build process. They will be executed once after which a snapshot of the image is taken. This image will then be used to deploy AVD sessionhosts.
Some layers may also need to execute scripts on the sessionhosts themselves, after they are deployed. For example, to configure firewall rules that should take effect after the sessionhost is properly deployed.
For this use-case, some special folders in the resources
directory can be used.
By putting scripts in these three folders, they will be automatically executed at specific times.
The following triggers are supported:
- Sessionhost setup scripts: Executed during the deployment of each sessionhost.
- Session scripts: Executed when a student logs in. Executed as the
SYSTEM
user. - User scripts: Executed when a student logs in. Executed as the student’s user.
For more information about these folders and which parameters are passed to the scripts, you can read more here.
There are two steps to make this work:
-
Put the scripts you want in their respective folders. Make sure you give them a name in the format
000(_pre/_post)_name.ps1.
By including_pre
or_post
in their name, you can control the order in which they are executed relative to the other layers. You can adjust their order within the layer, using the three digits at the start of the filename. -
Include the
default_layers/scripts_setup
layer when runningavdcli image package
. This step will be discussed in the Image Packaging section of this page.
5. Test each layer individually
Before you start building images in Azure, you should test each layer you’ve developed in isolation. You can do this easily on a (local) VM or a clean Windows machine. Make sure all the scripts work, before you move on. Debugging scripts in isolation on a VM you can interact with is much easier than debugging a problem when using the Azure Image Builder.
Create an Image Package
Once you’ve developed all the layers and tested them in isolation, you can move on to building the image in Azure.
The first step to this is to create an “Image Package”.
This is a folder, usually called ./out
,
that contains all the scripts, resources and configurations of all the layers you want to include in your image.
You create an Image Package by running the following command:
In this example we package all the commonly used default_layers
and the office365
and rstudio
images
into one Image Package.
This package will be written to the ./out
folder by default unless you specify another path using the -o
flag.
If you want to include even more layers, you can do so by specifying the -l
flag multiple times.
Image Package deployment
In the previous step, you created an Image Package. Now, we’ll deploy it to Azure and start the image building process.
Substitute the highlighted parameters with your own and run the command:
This guide assumes you already went through the Quick-Start guide and set up all the required resources. If not, please follow the guide on this page.
Debugging
You won’t be the first person for which the first image build does not work on the first try.
It rarely does.
Developing layers and building images involves debugging.
Debugging errors in a fully automated process is harder than debugging interactively on a (local) VM.
That’s why we recommend you to test your scripts as much as possible before you run avdcli package deploy
.
However, you will likely have to debug in the Azure Image Builder process as well.
You can follow these steps during your debug iterations:
- Navigate to AVD | Custom image templates in the Azure Portal.
- Find the name of the image template that failed and click on its staging resource group.
- If the image build already failed, you will find a storage account in this resource group that holds log files. If the image build is still ongoing, there will be a container resource. If you navigate to this container resource you will be able to see the live logs of the container that is executing the build steps.
Testing the image
Did you Image Builder finish successfully? Congrats. Now you can test it in a real Schoolyear exam.
- Does the image work as expected when you use it as a student?
- Does the exam environment meet the requirements of the educators?
- Are students blocked from accessing non-permitted resources?
To test the image in a Schoolyear, follow the steps in the Quick-Start guide to make the image available in your Schoolyear tenant, plan an exam with that image and try it out yourself first.