0
votes

I am trying to assign tags to an Azure Resource by passing them through an Azure DevOps pipeline, but cannot define the correct expression in the ARM template.

An Azure resource group deployment task is used in a DevOps Release pipeline to deploy a resource to Azure. Several pipeline variables are defined for tags to apply to that resource. These variables are passed through to the ARM Template by overriding the template parameters in the task. The ARM template defines a "tagsObject" parameter with a format of "tagName" and "tagValue" wrapped in an object. The issue is how to assign all of the tags provided by the tagsObject in the "tags" section of the ARM Template? The standard "tags": "[parameters('resourceTags')]" fails. What I'm after is for each object, extract the key-value pair and assign them to their corresponding item. Can this be done?

How to do the assignment? "tags": "[union(parameters('tagsObject'),json('{\"tagName\":\"tagValue\"}'))]",

Below is the variable object used in the Override template parameters of the Azure resource group deployment task:

-tagsObject {"tags":[
    {"tagName":"Application","tagValue":"$(tagApplication)"},
    {"tagName":"Description","tagValue":"$(tagDescription)"},
    {"tagName":"Environment","tagValue":"$(environmentLongName)"},
    {"tagName":"Department","tagValue":"$(departmentLongCode)"},
    {"tagName":"Business Owner","tagValue":"$(tagOwnerBusiness)"},
    {"tagName":"Technical Owner","tagValue":"$(tagOwnerTechnical)"},
    {"tagName":"Platform","tagValue":"$(tagPlatform)"},
    {"tagName":"Project","tagValue":"$(tagProject)"},
    {"tagName":"Solution Type","tagValue":"$(tagSolutionType)"}
]}

This is the Parameter in ARM Template:

"tagsObject": {
            "type": "Object",
            "defaultValue": "{}",
            "metadata": {
                "description": "Specifies all tags {\"tagName\":\"\",\"tagValue\":\"\"} wrapped in an object."
            }
        }
1
As far as I remember, ARM tags is an object (not an array), so you could define tagsObject like {"Application":"$(tagApplication)", "Environment":"$(environmentLongName)", ... }, pass it to template as parameter and then assign like "tags": "[parameters('resourceTags')]". No need to put "tags" part in the tagsObject itself.stackoverflowusrone
Thank you for this suggestion which is a better approach with simplicity at its core.Ian

1 Answers

0
votes

If you can, put all of those tags into a PowerShell hashtable like this:

$tagsObject = @{
  'Application'     = '$(tagApplication)'
  'Description'     = '$(tagDescription)'
  'Environment'     = '$(environmentLongName)'
  'Department'      = '$(departmentLongCode)'
  'Business Owner'  = '$(tagOwnerBusiness)'
  'Technical Owner' = '$(tagOwnerTechnical)'
  'Platform'        = '$(tagPlatform)'
  'Project'         = '$(tagProject)'
  'Solution Type'   = '$(tagSolutionType)'
}

Then assign the variable to the parameter with -tagsObject $tagsObject

Recommendation when using Azure DevOps (ADO) variables to fill out the tags values that are processed by a PowerShell command or script to deploy the ARM template -- You should use single-quotes to wrap the ADO variables. If any of the ADO variables happen to contain a $ character, the PowerShell will attempt to treat it as a PowerShell variable and replace it with what will likely be a null or empty value. The single-quotes will treat the ADO variable substitution as a literal string.

ADO variable: departmentLongCode = asdf$qwert

"$(departmentLongCode)" becomes asdf because $qwert variable probably doesn't exist.

'$(departmentLongCode)' becomes asdf$qwert as expected.

Maybe this wouldn't happen in your case but I have seen it happen with password variables.