5

Using jq, is it possible to replace the value of each parameter in the sample JSON with the value of the variable that is the initial value?

In my scenario, Azure DevOps does not carryout any kind of variable substitution on the JSON file, so I need to do it manually. So for example, say $SUBSCRIPTION_ID is set to abc-123, I'd like to use jq to update the JSON file.

I can pull out the values using .parameters[].value, but I can't seem to find a way of setting each individual value.

The main challenge here is that the solution should be reusable, and different JSON files will have different parameters, so I don't think I can use --argjson.

Example

Original JSON

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/parametersTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "subscriptionId": {
            "value": "$SUBSCRIPTION_ID"
        },
        "topicName": {
            "value": "$TOPIC_NAME"
        }
    }
}

Variables

SUBSCRIPTION_ID="abc-123"
TOPIC_NAME="SomeTopic"

Desired JSON

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/parametersTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "subscriptionId": {
            "value": "abc-123"
        },
        "topicName": {
            "value": "SomeTopic"
        }
    }
}
0

3 Answers 3

5

Use --argjson; essentially, you are just going to ignore the attempt at parameterizing the JSON and simply replace the values unconditionally.

jq --argjson x "$SUBSCRIPTION_ID" \
   --argjson y "$TOPIC_NAME" \
   '.parameters.subscriptionId.value = $x; .parameters.topicName.value = $y' \
   config.json
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the reply. The issue here though is that I need the solution to be reusable, and not every JSON file (all ARM Template parameters files) will be the same, thus I can't hard code the parameter names.
3

Export those variables so that you can access them from within jq.

export SUBSCRIPTION_ID TOPIC_NAME
jq '.parameters[].value |= (env[.[1:]] // .)' file

//. part is for leaving variables absent in the environment as is, you can drop it if not necessary

1 Comment

That woks perfectly, thank you. Azure DevOps exports variables out of the box, so that removes the need to specify anything in the task (which is way I couldn't use the answer that suggested --argjson.
1

Here is a "data-driven" approach based on the contents of the schema and the available environment variables:

export SUBSCRIPTION_ID="abc-123"
export TOPIC_NAME="SomeTopic"

< schema.json jq '.parameters 
    |= map_values(if .value | (startswith("$") and env[.[1:]]) 
                  then .value |= env[.[1:]] else . end)'

Notice that none of the template names appear in the jq program.

If your shell supports it, you could avoid the "export" commands by prefacing the jq command with the variable assignments along the lines of:

SUBSCRIPTION_ID="abc-123" TOPIC_NAME="SomeTopic" jq -f program.jq schema.json

Caveat

Using environment variables to pass in the parameter values may not be such a great idea. Two alternatives would be to provide the name-value pairs in a text file or as a JSON object. See also Using jq as a template engine

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.