jq: creating arrays for Direktiv 'foreach' states

Modified on Thu, 25 May, 2023 at 12:33 PM

The foreach state in Direktiv is a powerful state that will execute an action for an array of items passed to it, in parallel. However, it is sometimes difficult to understand how Direktiv interprets these arrays.

Let's use the following example JSON input:


{
   "detail":{
      "requestParameters":{
         "instancesSet":{
            "items":[
               {
                  "instanceId":"i-0772f323027e52c97"
               },
               {
                  "instanceId":"i-e272f3sdj447sac82"
               },
               {
                  "instanceId":"i-a872f323024e32c44"
               }
            ]
         }
      }
   }
}

We would like to run the foreach state for each of the instanceIds in the JSON object. Let's look at how this is implemented:


description: A simple foreach state

functions:
  - id: aws-cli
    service: aws-cli
    type: knative-namespace

states:
  #
  # For AWS: confirmed that the machine is in going into a terminated state, now we need to get volumes associated with the instance 
  #
  - id: get-instance-details-aws
    log: jq(.)
    # log: Retrieve all the volumes not marked for deletion
    type: foreach
    array: 'jq([.detail.requestParameters.instancesSet.items[] | { "instance-id": .instanceId }])'
    action:
      function: aws-cli
      input:
        access-key: "key"
        secret-key: "secret"
        region: "region"
        commands:
        - command: 'aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=jq(."instance-id")'

The jq statement creates the following object which is passed into the foreach loop:

[
  {
    "instance-id": "i-0772f323027e52c97"
  },
  {
    "instance-id": "i-e272f3sdj447sac82"
  },
  {
    "instance-id": "i-a872f323024e32c44"
  }
]

Let's break the jq statement down into it's parts:

  • .detail.requestParameters.instancesSet.items[] selects all of the sub-items in the items array
  • pipes this select into the next part of the jq query
  • { "instance-id": .instanceId } creates a new object called instance-id with the value of the instanceId key.
  • [ ... ] around the statement instructs jq to create an array of the newly created objects

The object passed to the foreach state is now a simple array, which in turn will be broken into its seperate parts and passed to the function as a top-level JSON object that looks like this:

{
"instance-id": "i-a872f323024e32c44"
}

The function can therefore address the instance-id directly using jq(.instance-id).


Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article