How to Create a hardened Ubuntu Pro 20.04 LTS shared image with Azure Image Builder

Setup your Shared Image Gallery

We will be using some pieces of information repeatedly, so we will create some variables to store that information. Then we will create the identity, image definition and gallery that we will need for the image.

Set variables for use throughout the tutorial

We will create the resource group below, so the name should be one you are not already using. We will delete the resource groups that we have created at the end of the tutorial.

# Resource group name - we are using ibUbuntuProGalleryRG in this example
# Datacenter location - we are using North Europe in this example
# Additional region to replicate the image to - we are using West Europe in this

Now we will set variables for the Gallery Name and Image Definition Name. The image will be displayed in the Azure Portal as sigName/imageDefName.

# name of the shared image gallery - in this example we are using myGallery
# name of the image definition to be created
# image distribution metadata reference name

Create a variable for your subscription ID. If you only have one, this will be the output of:
az account show -o json | grep id
If you have more than one, you can use
az account list -o table
and take the value from the SubscriptionId column for the subscription you would like to use 

for this tutorial.

Then set this to the variable as follows:

subscriptionID=<Subscription ID>

Now we are going to set variables for the Ubuntu Pro plan we are going to use in the tutorial. If you have an Ubuntu Pro private offer with Canonical, for example including 24x7 Technical Support with SLAs, you will have a custom Offer and Sku we can enter these here instead. If not, we will use the plan name and product for the public Ubuntu Pro from the Azure Marketplace.

# ProPlanPublisher the 'Publisher' field for the Marketplace VM Offer we 
want to start from
# ProPlanOffer the 'Offer' field for the Marketplace VM Offer we want to 
start from
# ProPlanSku the 'Sku' field for the Marketplace VM Offer we want to start from

Create required resources, identities and permissions

Create the resource group:

az group create -n $sigResourceGroup -l $location --subscription $subscriptionID

Image Builder will use the user-identity provided to inject the image into the Azure Shared Image Gallery (SIG). In this example, you will create an Azure role definition that has the granular actions to perform distributing the image to the SIG. The role definition will then be assigned to the user-identity.

# create user assigned identity for image builder to access the storage account
 where the script is located
identityName=aibBuiUserId$(date +'%s')
az identity create -g $sigResourceGroup -n $identityName --
subscription $subscriptionID

# get identity id
imgBuilderCliId=$(az identity show -g $sigResourceGroup -n 
$identityName --subscription $subscriptionID -o json | grep 
"clientId" | cut -c16- | tr -d '",')

# get the user identity URI, needed for the template

# this command will download an Azure role definition template, 
and update the template with the parameters specified earlier.
/12_Creating_AIB_Security_Roles/aibRoleImageCreation.json -o 

imageRoleDefName="Azure Image Builder Image Def"$(date +'%s')

# update the definition
sed -i -e "s/<subscriptionID>/$subscriptionID/g" aibRoleImageCreation.json
sed -i -e "s/<rgName>/$sigResourceGroup/g" aibRoleImageCreation.json
sed -i -e "s/Azure Image Builder Service Image Creation Role/$imageRoleDefName
/g" aibRoleImageCreation.json

# create role definitions
az role definition create --role-definition ./aibRoleImageCreation.json

# need to wait a bit here
sleep 45

# grant role definition to the user assigned identity
# If this gives an error, wait a bit longer and try again
az role assignment create \
    --assignee $imgBuilderCliId \
    --role "$imageRoleDefName" \
    --scope /subscriptions/$subscriptionID/resourceGroups/$sigResourceGroup

Create an image definition and gallery

To use Image Builder with a shared image gallery, you need to have an existing image gallery and image definition. Image Builder will not create the image gallery and image definition for you.

We will start by creating a gallery and image definition. First, we will create the Gallery:

az sig create \
    -g $sigResourceGroup \
    --gallery-name $sigName \
    --subscription $subscriptionID

Then, create an image definition. This uses the variables we set earlier.

az sig image-definition create \
   -g $sigResourceGroup \
   --gallery-name $sigName \
   --gallery-image-definition $imageDefName \
   --publisher $ProPlanPublisher \
   --offer $ProPlanOffer \
   --sku $ProPlanSku \
   --os-type Linux \
   --plan-name $ProPlanSku \
   --plan-product $ProPlanOffer \
   --plan-publisher $ProPlanPublisher \
   --subscription $subscriptionID

Customise a template for our deployment

Now we are going to create a template that contains the build instructions for the standard, “golden” image we want to create.

We can download a starting point for this from here


Then we can customise it to use the values we have set above. The sed commands below simply replace the <variable> placeholders in BasicCISUbuntuPro1804SIGTemplate.json with the values for the parameters that we set earlier:

sed -i -e "s/<subscriptionID>/$subscriptionID/g" 
sed -i -e "s/<rgName>/$sigResourceGroup/g" BasicCISUbuntuPro1804SIGTemplate.json
sed -i -e "s/<imageDefName>/$imageDefName/g" BasicCISUbuntuPro1804SIGTemplate.json
sed -i -e "s/<sharedImageGalName>/$sigName/g" BasicCISUbuntuPro1804SIGTemplate.json
sed -i -e "s/<region1>/$location/g" BasicCISUbuntuPro1804SIGTemplate.json
sed -i -e "s/<region2>/$additionalregion/g" BasicCISUbuntuPro1804SIGTemplate.json
sed -i -e "s/<runOutputName>/$runOutputName/g"
sed -i -e "s%<imgBuilderId>%$imgBuilderId%g" BasicCISUbuntuPro1804SIGTemplate.json
sed -i -e "s/<ProPlanPublisher>/$ProPlanPublisher/g" 
sed -i -e "s/<ProPlanOffer>/$ProPlanOffer/g" BasicCISUbuntuPro1804SIGTemplate.json
sed -i -e "s/<ProPlanSku>/$ProPlanSku/g" BasicCISUbuntuPro1804SIGTemplate.json
Next Post Previous Post
No Comment
Add Comment
comment url