Packer YAML Azure DevOps Pipeline Pt. 2 – Azure Compute Gallery

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:

Packer YAML Azure DevOps Pipeline - deploy resourcegroup via Azure Cli

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:

Packer YAML Azure DevOps Pipeline - Running deployment

Deployed:

Packer YAML Azure DevOps Pipeline - Created Azure Compute Gallery

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

Packer YAML Azure DevOps Pipeline - Created Azure Compute Gallery deployment

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:

Packer YAML Azure DevOps Pipeline - Created Azure Compute Gallery with paramaters

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:

32 thoughts on “Packer YAML Azure DevOps Pipeline Pt. 2 – Azure Compute Gallery”

  1. 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.

    Reply
  2. 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 ????

    Reply
    • 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

      Reply
  3. Hi Niels
    did you see this issue
    When it run the AddtoSharedImageGallery.ps1
    Connect-AzAccount : ClientSecretCredential authentication failed: A configuration issue is preventing authentication

    Reply
  4. 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

    Reply
  5. 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 ?

    Reply
    • 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

      Reply
  6. 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.

    Reply

Leave a Comment