I have a list of subnets defined in my *.parameter.json file.
"subnetAddressPrefixes": {
"value": [
{
"name": "primary",
"addressPrefix": "10.2.0.0/17"
},
{
"name": "APIManagementSubnet",
"addressPrefix": "10.2.246.0/24"
},
{
"name": "ApplicationGatewaySubnet",
"addressPrefix": "10.2.251.0/24"
}
]
}
I want to look this up inside my bicep using the name.
To access the value 'primary', I'm using a syntax like this one: subnetAddressPrefixes[0].name
I want to be able to look the value up by name using this or any other mechanism in Bicep.
subnetAddressPrefixes['primary']
Related
i have to create an ARM template an currently im stucked in using the variables with extendend values.
I define the variables
"variables": {
"NetWorkID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
}
And now i want to get the first subnet of the virtual Network.
I don´t know how to get the value.
i tested this but this doesn´t work:
"subnet": {
"id": "[variables('NetWorkID().subnet.ID')]"
}
Can i get a hint how to work with these variables?
usually you refer to subnets using the syntax bellow.
What you can do is pass the virtualNetworkName and subnet1Name as parameters and use the resourceid() expression.
"subnet": {
"id": "[resourceId(parameters('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnet1Name'))]"
}
Another way to do this, if you refer to the same subnet accross the arm template, is to build this resourceid in the variables instead of the resources and then use the variable in the resources properties.
Example:
"variables": {
"subnetId": "[resourceId(parameters('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnet1Name'))]"
},
"resources": [
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "xxxx",
"name": "xxxxx",
"location": "xxxxx",
"properties": {
"privateLinkServiceConnections": [
{
"name": "xxxxx",
"properties": {
"privateLinkServiceId": "xxxxx",
"groupIds": [
"blob"
]
}
}
],
**"subnet": {
"id": "[variables('subnetId')]"
}**,
"customDnsConfigs": [
{
"fqdn": "xxxxxx"
}
]
}
}
]
You can also try to list the existing subnets using the reference() function
"subnetId":"[reference(resourceId('Microsoft.Network/virtualNetworks', variables('vnetName')), '2022-01-01', 'Full').properties.subnets]"
I have an arm template that creates a key vault and a secrets array that creates secrets. I am trying to make the template ignore secrets creation if the array is empty.
Here is what I have.
Parameter
"secretsArray": {
"type": "array",
"defaultValue": [
{
"secretName": "secrets",
"secretValue": "value"
}
]
},
Resource:
{
"apiVersion": "2019-09-01",
"type": "Microsoft.KeyVault/vaults/secrets",
"name": "[concat(parameters('keyVaultName'), '/', parameters('secretsArray')[copyIndex()].secretName)]",
"dependsOn": [
"[variables('keyVaultId')]"
],
"copy": {
"name": "secretsCopy",
"count": "[if(equals(length(parameters('secretsArray')),0),1, length(parameters('secretsArray')))]"
},
"properties": {
"value": "[if(equals(length(parameters('secretsArray')),0),json('null'),parameters('secretsArray')[copyIndex()].secretName)]"
}
},
When I try to make the array empty like so:
"secretsArray": {
"type": "array",
"defaultValue": []
},
I get the error: The template resource [concat(parameters('keyVaultName'), '/', parameters('secretsArray')[copyIndex()].secretName)] is not valid: The language expression property array index '0' is out of bounds...
This is my first attempt at conditions so I could be way off. Any help would be much appreciated. Thanks
I am trying to create cosmos DB and running a copy function to create container in the ARM template. But I am getting the Expression Error.
The language expression property '0' can't be evaluated.', for both indexes
Here is the variable Part:
"autoscaleOptions" : {
"copy": [
{
"name": "autoscaleSettings",
"count": "[length(parameters('containers'))]",
"input": {
"throughput": "[parameters('containers')[copyIndex('autoscaleSettings')].throughput]",
"autoscaleSettings": {
"maxThroughput": "[if(parameters('containers')[copyIndex('autoscaleSettings')].autoscale, null(), parameters('containers')[copyIndex('autoscaleSettings')].maxThroughput)]"
}
}
}
]
}
How I am calling the variable:
{
"type": "Microsoft.DocumentDb/databaseAccounts/mongodbDatabases/collections",
"apiVersion": "2021-04-15",
"name": "[format('{0}/{1}/{2}', variables('accountName_var'), parameters('databaseName'), parameters('containers')[copyIndex()].name)]",
"copy": {
"count": "[length(parameters('containers'))]",
"name": "ContainerCopy"
},
"properties": {
"resource": {
"id": "[parameters('containers')[copyIndex('ContainerCopy')].name]"
},
"options": "[variables('autoscaleOptions')[copyIndex('ContainerCopy')].input]"
},
"dependsOn": [
"[resourceId('Microsoft.DocumentDB/databaseAccounts/mongodbDatabases', variables('accountName_var'), parameters('databaseName'))]",
"[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('accountName_var'))]"
]
}
Here I have uploaded the entire template which has all the parameters.
https://gist.github.com/PrakashRajanSakthivel/cc2495e82102d9c9569461eb4a96c75f
I am able to achieve it, its because of the autoscale and manual depends on one another which shouldn't. here is the working one. https://gist.github.com/PrakashRajanSakthivel/17cca682ec0aba049561975142e828f7
I have a template of container instance with container in azurecr.io
Is it possible to use an Azure Key Vault secret in an ARM Template?
The following examples do not work:
"imageRegistryCredentials": [
{
"server": "***.azurecr.io",
"username": "***",
"password": {
"reference": {
"keyVault": {
"id": "[resourceId(parameters('vaultSubscription'), parameters('vaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]"
},
"secretName": "[parameters('secretName')]"
}
}
}
],
I have tried it with:
"resources": [
{
...
"properties": {
"parameters":{
"secretPassword": {
"type": "securestring",
"reference": {
"keyVault": {
"id": "[resourceId(parameters('vaultSubscription'), parameters('vaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]"
},
"secretName": "[parameters('secretName')]"
}
}
},
And:
"imageRegistryCredentials": [
{
"server": "**.azurecr.io",
"username": "**",
"password": "[parameters('secretPassword')]"
}
],
Result:
"error": {
"code": "InvalidTemplate",
"message": "Unable to process template language expressions for resource '/subscriptions/**/resourceGroups/**/providers/Microsoft.ContainerInstance/containerGroups/**' at line '28' and co
lumn '9'. 'The template parameter 'secretPassword' is not found. Please see https://aka.ms/arm-template/#parameters for
usage details.'"
}
}'
So, I've created a workaround, which enables you to relatively simply use any keyvault secret in your template by using a publicly available template on github. See https://github.com/bobvandevijver/azure-arm-keyvault-secret-output for the example.
It would obviously be better if Microsoft just fixed this implementation, but it's something!
You can only use key vault reference in the parameters of the template (or nested template).
so you either need to move this part to the parameters section or move it to the nested template and use this as a parameter to the nested template. here is the sample to pass values from the kv to the nested template:
{
"apiVersion": "2017-05-10",
"name": "[concat('kvReference-', copyIndex())]",
"type": "Microsoft.Resources/deployments",
"copy": {
"name": "kvReference",
"count": 2
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "nested_template_uri"
},
"parameters": {
"cer": {
"reference": {
"keyVault": {
"id": "keyvaultId"
},
"secretName": "secretname"
}
}
}
}
},
and you can just use those inputs as parameters inside nested template
I've tried using copyIndex() to create subnets with different names but I get the error
"message": "Resource
/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks/ has two child
resources with the same name
([parameters('subnets').subnetProperties[copyIndex('subnets')].name)).
But I followed documation to use copy and this is what I've been using, so I'm not sure why is wouldn't move to the next name property:
"resources": [
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2016-03-30",
"name": "[parameters('virtualNetworkName')]",
"location": "[parameters('location')]",
"tags": "[parameters('virtualNetworkTags')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('vNetAddressSpaces')]"
]
},
"copy": [
{
"name": "subnets",
"count": "[parameters('numberOfSubnets')]",
"input": {
"name": "[parameters('subnets').subnetProperties[copyIndex('subnets')].name)",
"properties": {
"addressPrefix": "[parameters('subnets').subnetProperties[copyIndex('subnets')].addressPrefix]"
}
}
}
]
}
},
Param file:
"subnets":{
"value":{
"subnetProperties":[
{
"name":"firstSubnet",
"addressPrefix":"10.0.0.0/24"
},
{
"name":"secondSubnet",
"addressPrefix":"10.0.1.0/24"
}
]
}
},
I've also tried using copyIndex(), but that throws
template language expression evaluation failed: 'The template language
function 'copyIndex' has an invalid argument. The provided copy name '' doesn't exist in the
resource.
I think you messed up with the brackets in this line:
"name": "[parameters('subnets').subnetProperties[copyIndex('subnets')].name)",
It should look like:
"name": "[parameters('subnets').subnetProperties[copyIndex('subnets')].name]",
The last bracket is wrong. If the brackets does not match the complete expression will not processed. This will result in the same name on the second loop.
Greetings,
KirK