0

I have a variable in a template that holds a number of entries that will specify the value in my template. By this I mean I have

    "ipSecurityRestrictions" : {
      "denyAllInbound": 
      [
        {
          "ipAddress": "0.0.0.0/0",
          "action": "Deny",
          "priority": 100,
          "name": "Deny All Inbound"
        }
      ],
      "allowAppGatewayOnly": 
      [
        {
          "vnetSubnetResourceId": "[variables('appGatewaySubnet')]",
          "action": "allow",
          "priority": 100,
          "name": "Allow App Gateway"
        }
      ]
    }
  }

I currently use a simple if function to determine which to use based on a parameter (it's actually a little more complex than that but this is enough for the question.) So at the moment I have something like

[if (equals(parameters('a'), 'allowAppGatewayOnly'), variables('ipSecurityRestrictions').allowAppGatewayOnly, variables('ipSecurityRestrictions').denyAllInbound)]

which quite happily works. However, I want to add another entry to the variable and I don't like the idea of having an if chain in there, it's going to get ugly very soon.

So I was trying various ways of using indirection based on the value of the parameter (and all of this is inside a copy loop and different entries in the parameter array could have different entries).

I have tried things like

"[variables('ipSecurityRestrictions')[parameters('appservices')[copyIndex()].ipSecurityRestrictions]]"

but the fact that I'm asking means it didn't work. [edit: it does actually work - if the parameter value is correct that is and doesn't have a stray single quote in it!]

Is it possible to do this in ARM templates or am I stuck with nested if functions calls?

Thanks

Alan Mullett
  • 103
  • 4

1 Answers1

1

You can achieve this using a parameter selecting which object you want and then using that as part of the object selection. You need to also remove the Array syntax from your "ipSecurityRestrictions" objects, as they are all arrays of 1, which has no benefit and causes you problem.

The example below allows selecting which object to use using a parameter, and then uses that in the output. You can expand on this to do what you need.

{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
    "ipRestriction": {

        "type": "string",
        "allowedValues": [
            "denyAllInbound",
            "allowAppGatewayOnly",
            "allowAll"
        ],
        "metadata": {
            "description": "description"
        }
    }
},
"variables": {

    "ipSecurityRestrictions": {
        "denyAllInbound": {
            "ipAddress": "0.0.0.0/0",
            "action": "Deny",
            "priority": 100,
            "name": "Deny All Inbound"
        },

        "allowAppGatewayOnly": {
            "action": "allow",
            "priority": 100,
            "name": "Allow App Gateway"
        },
        "allowAll": {
            "action": "allow",
            "priority": 100,
            "name": "Allow All"
        }

    }
},
"resources": [
],
"outputs": {
    "example": {
        "type": "string",
        "value": "[variables('ipSecurityRestrictions')[parameters('ipRestriction')].name]"
    }
},
"functions": [
]

}

Sam Cogan
  • 38,158
  • 6
  • 77
  • 113
  • Many thanks for your reply which confirmed that it should work as I originally thought it should, but I couldn't get it working. Taking your example and building up on it I found a very silly mistake in my parameter file where a stray single quote had made it inside the json double quotes, so I had {"ipRestriction": "allowAppGatewayOnly'"}, finding that single quote was only discovered when building up again from your example. – Alan Mullett Mar 03 '20 at 10:05