Packer is a great tool to build images. This blog is about using YAML to build your Packer Azure DevOps Pipeline. When using YAML, it is very easy to replicate your pipeline to other Azure DevOps organizations. This post is about adding the managed image to the Azure Compute Gallery.
Prerequisites
You need to have your Azure DevOps organization and Azure tenant setup. I have written a blog on how to do so. This is the link.
You need to have Pt.1 of this series completed. This is the link.
Also, you need to have Bicep and Azure CLI set up to use my templates.
After that, you are ready to start this blog!
Create Azure Compute Gallery
Firstly, we need to create the Azure Compute Gallery and an Image Definition. We use Bicep to do so.
Log on with Azure CLI to the Azure Resource Manager using the command:
Az Logon
After that, select the appropriate subscription:
az account set --subscription <subscription id>
Next, create the resource group where we are deploying the Azure Computer Gallery too. For Example:
az group create --location WestEurope --name RG_WE_AVD_AzureComputeGallery
As a result, the resource group has been created:

Now it is time to create the Azure Compute Gallery. This is the bicep template to do so. Please save the following code as a .bicep file so we can deploy it via Azure CLI.
param customername string = 'NKO' var SIGName = '${customername}_AzureComputeGallery' //parameters for Tags param Tag_owner string = 'NKO' param Tag_costCenter string = 'AzureComputeGallery' param Tag_Tier string = 'Production' resource symbolicname 'Microsoft.Compute/galleries@2019-03-01' = { name: SIGName location: resourceGroup().location tags: { Owner: Tag_owner CostCenter: Tag_costCenter Tier: Tag_Tier } properties: { description: SIGName identifier: {} } }
When you run this file an Azure Compute Gallery called “NKO_AzureComputeGallery” is created. If you would like to change the name, please edit the parameter “customername” or run the bicep file with parameters. I will show both options.
Run the bicep file without setting the parameter via Azure CLI:
az deployment group create --resource-group RG_WE_AVD_AzureComputeGallery --template-file <path-to-template>
Running:

Deployed:

You can also see the deployed templates in the Deployments option:

Run the bicep file by setting the parameter via Azure CLI:
az deployment group create --resource-group RG_WE_AVD_AzureComputeGallery --template-file <path-to-template> --parameters customername='NielsKok.tech'
Deployed:

Lastly, we need to create the image definition on which our image is based. This contains the Offer, SKU, OS Type, and the resources this may be deployed to. These ranges are very big. I have set the CPU resources from 2 to 128 vCPU’s and the min to 1024 MB and the max to 256000 MB. If your VM needs to have more or fewer resources please change these values.
This is the template. Again, save this file a .bicep file.
//parameters for Tags param Tag_owner string = 'NKO' param Tag_costCenter string = 'AzureComputeGallery' param Tag_Tier string = 'Production' //parameters for Image Definition param azurecomputegalleryname string = 'NKO_AzureComputeGallery' param ImageName string = '${azurecomputegalleryname}/AVDImage' param Offer string = 'Windows10' param SKU string = '21H1' param vCPUmin int = 2 param vCPUmax int = 128 param memorymin int = 1024 param memorymax int = 256000 param osState string = 'Generalized' param osType string = 'Windows' var ImageDescription = '${Offer} for Virtual Machines' resource AVDImage 'Microsoft.Compute/galleries/images@2019-03-01' = { name: ImageName location: resourceGroup().location tags: { Owner: Tag_owner CostCenter: Tag_costCenter Tier: Tag_Tier } properties: { description: ImageDescription osType: osType osState: osState endOfLifeDate: '01-01-2099' identifier: { publisher: 'NKO' offer: Offer sku: SKU } recommended: { vCPUs: { min: vCPUmin max: vCPUmax } memory: { min: memorymin max: memorymax } } purchasePlan: { name: 'string' publisher: 'string' product: 'string' } } }
In addition, please note that the “ImageName” parameter is an aggregated parameter. The Azure Compute Gallery name needs to be part of this variable. Please make sure you use the correct name from the previous deployment.
Run the bicep file with this code: (I have explained the parameter option in the previous deployment.)
az deployment group create --resource-group RG_WE_AVD_AzureComputeGallery --template-file <path-to-template>
Deployed:

Create Packer YAML Azure DevOps Pipeline
The next step is adding an upload configuration to our Pipeline in Azure DevOps. That way, our managed image from part 1 is automatically uploaded to the Azure Compute Gallery.
I have created a function in Powershell to facilitate the upload process. This also makes it very easy to add this to our YAML pipeline.
Firstly please add these files to your Azure DevOps repository:
Powershell function for upload.
YAML Pipeline with the upload.
Add these to your DevOps repository:

Lastly, we create the new pipeline from the YAML file.
Go pipelines and click on New pipeline:

Choose Azure Repos Git:

Select the appropriate repository:

Choose “Existing Azure Pipelines YAML file”:

After that, select the correct YAML file:

You now see the YAML file. We need to edit some pieces of the file.
Firstly, you need to edit the “poolname” and the “variable groupname”:

Secondly, you need to edit the parameters from the Powershell Function:

Make sure you use the parameters that match your environment.
After that run the pipeline!
Running the Pipeline
Firstly, the image is created according to the first part of this series:

After that the image will be uploaded to the Azure Compute Gallery:

After that, it is available in the resourcegroup:

And in the Azure Compute Gallery:

hi Niels
I get this error when the pipline runs AddtoSharedImageGallery.ps1
C:\vsts-agent-win-x64-2.196.2\_work\2\s\PSScripts\AddtoSharedImageGallery.ps1 : Cannot convert ‘System.Object[]’ to
the type ‘System.String’ required by parameter ‘ImageName’. Specified method is not supported.
Hi Raf,
What do you use as input for the parameter ImageName?
Thanks,
Niels
Where can i find it?
in the AddtoSharedImageGallery.ps1 i dident change
found the bug sorry
Good to hear!
Hi Niels
still the same
parameter ImageName
param ImageName string = ‘NKO_AzureComputeGallery/AVDImage’
What is the name of your Azure Compute Gallery?
NKO_AzureComputeGallery
Can you send me a screenshot of the configuration?
C:\agent\_work\1\s\PSScripts\AddtoSharedImageGallery.ps1 : The term ‘Connect-AzAccount’ is not recognized as the name o
f a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, veri
fy that the path is correct and try again.
At C:\agent\_work\_temp\azureclitaskscript1657729528205.ps1:3 char:1
+ . ‘C:\agent\_work\1\s\PSScripts\AddtoSharedImageGallery.ps1’ -Imagerg …
Getting this error al the time, can u please help me ????
Hi Sander,
You need to install the Az module on your agent in order to get these commands to work. Please run the command: “Install-Module Az” as administrator.
You can also try to upload the image by using a bicep template. This is my new method. Will create a post about it later.
Thanks,
Niels
Niels , Idd dankjewel.
Ik las op je site dat je uit NL kwam.
Gr,
Sander
Klopt! Leuk om te lezen dat je op mijn site terecht bent gekomen.
Gr,
Niels
Hi Niels
did you see this issue
When it run the AddtoSharedImageGallery.ps1
Connect-AzAccount : ClientSecretCredential authentication failed: A configuration issue is preventing authentication
btw my agent is a Linux vm
You need to edit the variables if you use a linux based host. All “_” need to be “.”.
Hi Niels
When i run the add the share image gallery the copt dont work
When i got to the portal i see the image but when i want to add manule in to the SIG i dont see it.
When i run the script it get
Id Name PSJobTypeName State HasMoreData Location Command
— —- ————- —– ———– ——– ——-
5 Long Running… AzureLongRun… Failed True localhost New-AzGalleryImageVersion
Try to run it manually without the the pipelines agent. Then you know what the problem is.
got it 🙂 works!
NIce 🙂
Hi Niels
something chnage i think for MS side and the script dont work
Cannot convert ‘System.Object[]’ to the type ‘System.String’ required by parameter ‘ImageName’. Specified method is not supported.
dose it still work for you ?
Hi David,
Which script doesn’t work?
Thanks,
Niels
hi Niels
for today i get this error ##[error]request to https://checkpoint-api.hashicorp.com/v1/check/packer failed, reason: read ECONNRESET
do you have as well is it more packer or something on my side ?
Hi David,
At what stage do you get this error?
Thanks,
Niels
hi
Use Packer Latest
Hi David,
I ran it yesterday and had no issues. Could you maybe try to set a static version of Packer and see if this works?
Otherwise, does your agent have access to download Packer?
Thanks,
Niels
Hi Niels
Now i get this error
on /__w/1/s/Packer/Windows10AVDImage.pkr.hcl line 123:
(source code not available)
The source azure-arm is unknown by Packer, and is likely part of a plugin that
is not installed.
You may find the needed plugin along with installation instructions documented
on the Packer integrations page.
Hi David,
You probably have a old version of my packer template. Look at the GitHub repo for the latest version. This is the link:
https://github.com/Ruthhl3ss/public/blob/main/Packer-Templates/Windows10AVDImage.pkr.hcl
Goodluck!
Niels