How to iterate through a JSON file in Azure DevOps Pipelines?

Viewed 634

Scene:

I am using Azure DevOps pipelines as a security separator, so that my front end is not directly accessing my AKS.

(Above is a business requirement I am not able to avoid or change in any way)

What I got so far:

I am able to put together a html post body with the information that I will be getting from my front end, and I am able to understand it and parse it out as JSON inside the Azure DevOps Pipeline. (using Python)

Issue:

I need to must be able to iterate through each of the object in my JSON and execute actions as indicated.

JSON example:

{
  "actions": [
    {
      "action": "action(0)",
      "config": {
        "actionType": "Start"
        "stage": "test",
        "region": "North",
        "version": "v756"
        "customer": "Hans"
      }
    },
    {
      "action": "action(1)",
      "config": {
        "actionType": "Stop"
        "stage": "test",
        "region": "East",
        "version": "v752"
        "customer": "Christian"
      }
    },
    {
      "action": "action(2)",
      "config": {
        "actionType": "Delete"
        "stage": "prod",
        "region": "South",
        "version": "v759"
        "customer": "Anderson"
      }
    }
  ]
}

** Edited (malformed JSON example)

TypeScript that generates my testing data

const value = {
  actionType: "Create",
  stage: "test",
  region: "North",
  version: "v753",
  customer: "Hans"
}

interface Action {
    readonly action: string;
    readonly config: typeof value;
}

const actions: Array<Action> = [];

for (let i = 0; i < 3; i++) actions.push({
    action: `action(${i})`,
    config: value
})

const result = JSON.stringify({ actions });

const body = {
    templateParameters: {
        actions: {
            value: result
        }
    }
}

** Edited: Added the TypeScript

Current pipeline

name: Test-Deploy-$(Date:yyyyMMdd)-$(Date:hh-mm)$(Rev:.r)

pool:
  vmImage: ubuntu-latest

parameters:
- name: actions
  type: object
  default: []

stages:
  - stage: test_stage
    displayName: Test stage
    jobs:
      - job: test
        displayName: Test the values
        steps:
        - ${{ each action in parameters.actions}}:
          - task: PowerShell@2
            displayName: Print out the "Action"-variable
            inputs:
              targetType: 'inline'
              script: '"${{action}}"'

** Edited: Added the pipeline as it stands

My current thinking:

I would like to be able to iterate through the actions in a "for-each" fashion. Like in this pseudo pipeline script below:

- ${{ each action in $(actions) }}:

But I am not able to come up with exactly how that would be done in Azure DevOps Pipelines, so I am hoping that someone here can figure it out with me :)

1 Answers

${{ each }} is a template expression. They're intended for use with parameters rather than variables, because they are evaluated at compile time (so $(variablename) can't have a value yet).

Now, I've not actually tried this myself, but the Runs API has a JSON request body element called templateParameters, which takes an object. What you could try is something like this:

  1. Add a parameter to your pipeline, like:
parameters:
- name: actions
  type: object
  default: []
  1. When submitting the Runs API call to run your pipeline, include something like:
{ 
  "previewRun": true,
  "templateParameters": {
    "actions": {
       ... your JSON actions content as generated in your question ... 
    },
  ... other parameters to your JSON run request
}
  1. In your pipeline, reference
- ${{ each action in parameters.actions }}:

The previewRun parameter will cause Azure Pipelines to not run the pipeline, but to return the compiled template for debugging and validation purposes. Remove it when you're ready to execute it.

Also, you'll likely need to do some experimenting with templateParameters to get something acceptable to the pipeline, like declaring it as an array "templateParameters": [ { "actions": [ your actions ] } ] (as I said, I haven't actually done this, but the documentation suggests this might be a good path to explore).

Related