1

is there any way to loop inside one object type Parameters again in Azuredevops

I am planning to automate tag create/update to resources using Azuredevops pipeline and I decided to use Azure CLI command for the same(not sure if this is the right choice)

So I created a template (template.yaml) file as below.

parameters:
- name: myEnvironments
  type: object
- name: tagList
  type: object

stages:
  - ${{ each environment in parameters.myEnvironments }}:  
    - stage: Create_Tag_${{ environment }}
      displayName: 'Create Tag in ${{ environment }}'
      pool:
          name: my-spoke
      jobs:
        - ${{ each tag in parameters.tagList }}:
          - ${{ if eq(tag.todeploy, 'yes') }}:
            - job: Create_Tag_For_${{ tag.resourcename }_${{ environment }}}
              displayName: 'Tag the reource ${{ tag.resourcename }'
              condition: eq('${{ tag.todeploy }}', 'yes')  
              workspace:
                clean: all
              pool:
                name: myspoke
              steps:
              - task: AzureCLI@2
                displayName: "Tag the resource"
                inputs:
                  azureSubscription: ${{ variables.subscription }}
                  scriptType: 'bash'
                  scriptLocation: 'inlineScript'
                  inlineScript: az tag update --resource-id ${{ tag.resourceid }} --operation replace --tags key1=value1 key3=value3

              

and my pipeline input as below

stages:
  - template: template.yaml
    parameters:
      myEnvironments:
      - development
################################################################################################
#                 Tag List                                                                   #
################################################################################################
      tagList:
      - resourcename: myaksservice
        todeploy: yes
        tagname1: tagvalue of 1
        tagname2: tagvalue of 2
        .
        .
        .
        .   
        tagn    : tagvalue of n
        
      - resourcename: myappservice
        todeploy: yes       
        tagname1: tagvalue of 1
        tagname2: tagvalue of 2
        .
        .
        .
        .   
        tagn    : tagvalue of n     
        
      - resourcename: mystorageaccount
        todeploy: yes     
        tagname1: tagvalue of 1
        tagname2: tagvalue of 2
        .
        .
        .
        .   
        tagn    : tagvalue of n     

            

But I was able to loop through the envlist , and the taglist elelments, but not able to loop through the tag values for each resources to crate them at a shot.

Vowneee
  • 956
  • 10
  • 33
  • I don't see myEnvironments in the main yml, only envlist. Are they the same thing? – Bowman Zhu-MSFT Dec 05 '22 at 08:56
  • yes,, that was a typo. I corrected above. – Vowneee Dec 05 '22 at 09:11
  • See my answer. If I misunderstand, feel free to let me know.:) – Bowman Zhu-MSFT Dec 05 '22 at 10:30
  • @BowmanZhu-MSFT, Didnt work as I expected. Below is what I tried. my requirement is to iterate the tags for each resources accordingly. What I tried is as below. – Vowneee Dec 05 '22 at 19:16
  • stages: - ${{ each environment in parameters.myEnvironments }}: - stage: displayName: 'Create Tag in ${{ environment }}' jobs: - ${{ each tag in parameters.tagList }}: - ${{ each tagcontent in tag }}: - ${{ if and(ne(tagcontent.Key, 'resourcename'),ne(tagcontent.Key, 'todeploy')) }}: - job: displayName: 'Tag the reource ${{ tag.resourcename }}' steps: – Vowneee Dec 05 '22 at 19:27
  • - task: AzureCLI@2 displayName: "Tag the resource" inputs: azureSubscription: "xxxxxxxxx" scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: 'az tag update --resource-id ${{ tag.resourcename } --operation replace --tags ${{ tagcontent.Key }}=${{ tagcontent.Value }}' – Vowneee Dec 05 '22 at 19:27

1 Answers1

2
trigger:
- none

pool:
  vmImage: ubuntu-latest
parameters:
- name: myEnvironments
  type: object
  default:
  - 111
  - 222
  - 333
- name: tagList
  type: object
  default:
  - resourcename: myaksservice
    todeploy: yes
    tagname1_1: tagvalue of 1
    tagname2_1: tagvalue of 2
  - resourcename: myappservice
    todeploy: yes
    tagname1_2: tagvalue of 1
    tagname2_2: tagvalue of 2
  - resourcename: mystorageaccount
    todeploy: yes
    tagname1_3: tagvalue of 1
    tagname2_3: tagvalue of 2

stages:
- ${{ each environment in parameters.myEnvironments }}:
  - stage: 
    displayName: 'Create Tag in ${{ environment }}'
    pool:
      vmImage: ubuntu-latest
    jobs:
      - ${{ each tag in parameters.tagList }}:
        - ${{ each tagcontent in tag }}:
          - ${{ if and(ne(tagcontent.Key, 'resourcename'),ne(tagcontent.Key, 'todeploy')) }}:
            - job:
              displayName: 'Tag the reource ${{ tag.resourcename }}'
              steps:
              - task: PowerShell@2
                inputs:
                  targetType: 'inline'
                  script: |
                    # Write your PowerShell commands here.
                    
                    Write-Host "Hello World"
                    Write-Host ${{tagcontent.Key}}

For the first stage, the pipeline will foreach the tagname in taglist and output:

tagname1_1
tagname2_1
tagname1_2
tagname2_2
tagname1_3
tagname2_3

So the key is 'object.Key' and 'object.Value', use them to get other contents in yaml object.

Bowman Zhu-MSFT
  • 4,776
  • 1
  • 9
  • 10
  • But How I can iterate this value over this devops task, because for each resource the number of tags will be different. for example, depend on the number of tags, need to iterate that much keyvalue pairs to the az command key1=value1 key3=value3 – Vowneee Dec 05 '22 at 15:06
  • - task: AzureCLI@2 displayName: "Tag the resource" inputs: azureSubscription: ${{ variables.subscription }} scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: az tag update --resource-id ${{ tag.resourceid }} --operation replace --tags key1=value1 key3=value3 – Vowneee Dec 05 '22 at 15:07
  • The above task is working with the for each loop, but the issue what i am facing is, in the command part I am using "--operation replace" which is for always setting the tags only from the above list of tags. But here as part of the for each , the final value only getting added as its replacing the previous values. There is another operation called "merge", which I cant use as we need to always replace the content from this pipeline. – Vowneee Dec 06 '22 at 12:40
  • I raised new question with the issues- https://stackoverflow.com/questions/74722439/azure-resource-tag-bulk-update-using-azuredevops-pipeline – Vowneee Dec 07 '22 at 20:17
  • @Vowneee If you use replace operation, then all of the previous tags be forgot is expected. – Bowman Zhu-MSFT Dec 08 '22 at 03:31