Search code examples
azureazure-devopsyamlazure-pipelines

Azure DevOps YAML template passing hashset/map/dictionary/object - key value?


Say I have a main azure devops pipeline azure-pipelines.yml in which I call into my template deploy.yml.

In the main pipeline I'd like to be able to declare either a variable or a parameter of type hashset / map / dictionary or any other key value structure that I can then pass to the template.

I can see that it's possible to pass in an object type, but I can't wrap my head it's usage. How could I achieve the following?

Note the appSettings: {"key1":"value1","key2":"value2"} in azure-pipelines.yml is a fantasy, but showcases pretty well how I'd like this to work.

azure-pipelines.yml:

trigger:
 - main

- job: deploy
  pool:
    vmImage: ${{ parameters.poolVmImage }}
  steps:
  - template: deploy.yml
    parameters:
      azureServiceConnection: ${{ parameters.azureServiceConnection }}
      resourceGroupName: 'foo'
      appServiceName: 'bar'
      appSettings: {"key1":"value1","key2":"value2"}

deploy.yml:

parameters:
  - name: azureServiceConnection
  - name: resourceGroupName
  - name: appServiceName 
  - name: appSettings

steps:
- task: AzureCLI@2
  displayName: Deploy zip
  name: deployZip
  inputs:
    azureSubscription: ${{ parameters.azureServiceConnection }}
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: |
      az webapp deployment source config-zip \
        -g ${{ parameters.resourceGroupName }} \
        -n ${{ parameters.appServiceName }} \
        --src ./deployment.zip

      az webapp config appsettings set \
        -g ${{ parameters.resourceGroupName }} \
        -n ${{ parameters.appServiceName }} \
        --settings ${{ parameters.appSettings }}

Solution

  • How could I achieve the following?

    You can indeed use object type parameters.

    But in the template, you cannot use multiple object parameters at once, so you need to use each expression to loop through each object.

    For example: - ${{ each setting in parameters.appSettings }}:

    Here is my sample, you could refer to:

    Deploy.yml:

    parameters:
      - name: azureServiceConnection
      - name: resourceGroupName
      - name: appServiceName 
      - name: appSettings
        type: object
        default: []
    
    steps:
    
    - task: AzureCLI@2
      displayName: Deploy zip
      name: deployZip
      inputs:
        azureSubscription: ${{ parameters.azureServiceConnection }}
        scriptType: 'bash'
        scriptLocation: 'inlineScript'
        inlineScript: |
          az webapp deployment source config-zip \
            -g ${{ parameters.resourceGroupName }} \
            -n ${{ parameters.appServiceName }} \
            --src ./deployment.zip
    
    
    - ${{ each setting in parameters.appSettings }}: 
      - task: AzureCLI@2
        displayName: Deploy settings
        inputs:
          azureSubscription: ${{ parameters.azureServiceConnection }}
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            az webapp config appsettings set \
              -g ${{ parameters.resourceGroupName }} \
              -n ${{ parameters.appServiceName }} \
              --settings ${{ setting }}
    

    azure-pipelines.yml:

    trigger:
     - none
    
    parameters:
    - name: InstanceArgs 
      type: object
      default: [key2=value2,key3=value3]
    jobs:
    - job: deploy
      pool:
        vmImage: windows-latest
      steps:
    
      - template: deploy.yml
        parameters:
          azureServiceConnection: '${{ parameters.azureServiceConnection }}'
          resourceGroupName: 'foo'
          appServiceName: 'bar'
          appSettings: ${{ parameters.InstanceArgs }}
    

    Note: Since the parameters in the template are object type , the same type of parameters need to be set in the main yaml file to pass the object.

    Workflow: Pass the object type parameters to the template. The template will run the deploy zip command first. Then it will traverse each object passed, and use the config settings command to pass them to the webapp one by one.

    Result:

    enter image description here