[RESOLVED] ARM Template: multiple address prefixes - how to pass via parameters

Michael Ingraham 11 Reputation points
2022-06-16T22:03:52.723+00:00

I am trying to pass some of the cidr address prefixes through an entered parameter. For example, I need to pass the following property for my network security group security rule:

"sourceAddressPrefixes": [
"y.y.y.y/32",
"x.x.0.0/16"
]

The y.y.y.y/32 address range is what I'm trying to parameterize.

The entry in the "parameters:" section:

"remoteOfficeIpCidr": {
"defaultValue": "",
"type": "String"
}

I have tried to pass the property as a list of address ranges without enclosing them in double quotes (equivalent to using '' below). Template syntax validates but the deployment fails. So, I am trying to enclose each address range in double quotes (The deployment also fails if I pass the addresses enclosed by single quotes).

I have tried escaping the quotes:

"sourceAddressPrefixes": [
"[concat(if(not(empty(parameters('remoteOfficeIpCidr'))), concat('\"',parameters('remoteOfficeIpCidr'),'\",'),''), '\"x.x.0.0./16\"')]"
]

More generally, I iterated the following:

"sourceAddressPrefixes": [
"[concat(if(not(empty(parameters('remoteOfficeIpCidr'))), concat(<myQuotingSyntax>,parameters('remoteOfficeIpCidr'),<myQuotingSyntax>,','),''), concat('\"','x.x.0.0./16',<myQuotingSyntax>))]"
]

I have tried to get the template to work using the following strings in each instance of <myQuotingSyntax>:

  • '' (empty string - two single quotes)
  • '\"' (escaped double quote enclosed by single quotes)
  • '"' (double quote enclosed by single quotes)
  • '""' (repeated double quotes enclosed by single quotes)
  • ''' (triple single quotes)

(<backTick> (`) would not render properly here)

  • <backTick>" (<backTick> followed by double quote)
  • <backTick>"<backTick> (double quote enclosed by <backTick>)
  • "
  • %22x

Some of these pass template syntax validation but fail during the deploy. But none are successful.

I'm out of ideas. I welcome any and all suggestions.

Azure Lab Services
Azure Lab Services
An Azure service that is used to set up labs for classrooms, trials, development and testing, and other scenarios.
308 questions
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Michael Ingraham 11 Reputation points
    2022-06-27T22:55:10.53+00:00

    I was finally able to add address prefixes as parameters. The key was to define the prefixes as arrays with string elements and then to use concat to concatenate the prefix "arrays". If one of the prefix arrays is left empty, the concatenation results in just the array with non-empty elements. I'm not sure this is the best way, but it works (whereas concatenating strings does not).

    param corpSourceAddressPrefix array = ['x.x.0.0/16']
    param remoteSourceAddressPrefix array = []

    sourceAddressPrefixes: concat(corpSourceAddressPrefix,remoteSourceAddressPrefix)

    generates sourceAddressPrefixes: [x.x.0.0/16]

    Accordingly

    param corpSourceAddressPrefix array = ['x.x.0.0/16']
    param remoteSourceAddressPrefix array = [y.y.y.y/32]

    sourceAddressPrefixes: concat(corpSourceAddressPrefix,remoteSourceAddressPrefix)

    generates sourceAddressPrefixes: [x.x.0.0/16,y.y.y.y/32]

    1 person found this answer helpful.
    0 comments No comments

  2. Sam Cogan 10,812 Reputation points Microsoft Employee Volunteer Moderator
    2022-06-17T13:07:46.967+00:00

    First up, if your starting new templates I would very much reccomend you switch to using Bicep rather than ARM. Bicep is the successor to ARM and is much easier to get started with.

    However, if you are using ARM, then there is no need to quote the value at all, you just need to pass the paramter in. The following template works just fine:

    {  
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",  
        "contentVersion": "1.0.0.0",  
        "parameters": {  
            "ip": {  
                "type": "string",  
                "defaultValue": "10.0.0.1",  
                "metadata": {  
                    "description": "description"  
                }  
            }  
        },  
        "functions": [],  
        "variables": {},  
        "resources": [  
            {  
                "name": "networkSecurityGroup1",  
                "type": "Microsoft.Network/networkSecurityGroups",  
                "apiVersion": "2020-11-01",  
                "location": "[resourceGroup().location]",  
                "properties": {  
                    "securityRules": [  
                        {  
                            "name": "nsgRule1",  
                            "properties": {  
                                "description": "description",  
                                "protocol": "Tcp",  
                                "sourcePortRange": "*",  
                                "destinationPortRange": "*",  
                                "sourceAddressPrefixes": [  
                                    "[parameters('ip')]"  
                                ],  
                                "destinationAddressPrefix": "*",  
                                "access": "Allow",  
                                "priority": 100,  
                                "direction": "Inbound"  
                            }  
                        }  
                    ]  
                }  
            }  
        ],  
        "outputs": {}  
    }  
    
    0 comments No comments

  3. Michael Ingraham 11 Reputation points
    2022-06-17T17:57:23.447+00:00

    For this exercise, the parameter is only one of the address prefixes I am trying to pass. The scenario is such that I have a corporate IP prefix which is static so I want to hard code that and not query that from the user each time the deployment is run. Next is the user(s)' session ingress IP prefix (i.e., their ISP IP address). I want this to be entered via a parameter. However, the user may be directly on the corporate network and therefore this parameter may be left blank. It is from these two prefixes (or just one), that I want to pass the properly formatted string to the SourceAddressPrefixes property. Here, the property wants each prefix enclosed in double quotes. I know because if I pass the ISP IP range and have not enclosed each prefix in double quotes the deploy fails but fails if I leave the parameter empty. The issue is that these have to be comma separated. So, when empty, there's an extra comma.

    If I pass a value, the syntax below works because it encloses the parameterized prefix in double quotes. Without the quotes, it fails.

    "sourceAddressPrefixes": [
    "x.x.0.0/16",
    "[if(not(empty(parameters('remoteOfficeIpCidr'))),parameters('remoteOfficeIpCidr'),'')]"
    ]

    So, the issue comes when I try to create the complete string in an expression so I either put in one prefix (empty parameter) or I add a comma and the second prefix. But, adding double quotes to the expression in any way shape or form fails the syntax checking. The only time syntax is validated is if I escape the quotes... but then it fails to deploy because the backslash used to escape the quotes ( \") is "rendered" as part of the resulting string.

    I also tried this

    "sourceAddressPrefixes": [
    "[concat(if(not(empty(parameters('remoteOfficeIpCidr'))), concat(parameters('remoteOfficeIpCidr'),'\",\"'),''), 'x.x.0.0/16')]"
    ]

    P.S.

    Bicep... OK. I am brand new and all I'm going by is the exported template from my manually deployed resources (net, vnet, nsg, public IP, etc.) that create a vm. I was just working with the syntax the export gave me. Is there a way to specify Bicep as the "language" the template is exported in?

    I found the Azure CLI decompile option. I'll give that a shot.

    0 comments No comments

  4. Michael Ingraham 11 Reputation points
    2022-06-22T16:57:39.133+00:00

    @Sam Cogan

    I gave Bicep a try. I used the Azure CLI to decompile the json template. This forum is not letting me post the actual code snippet so I am having to post my message as a file attachment.

    213887-az-community-template-question-follow-up.txt

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.