ARM - get VMSS's private IPs - azure

I have a VMSS deployed with am ARM template.
I want add it's first VM's IP address to the output.
In the Azure Resource Explorer - I see resource as:
...
"ipConfigurations": [
{
"name": "jm-website-script-4-master-ip",
"id": "/subscriptions/0a4f2b9c-***-40b17ef8c3ab/resourceGroups/jm-website-script-4/providers/Microsoft.Compute/virtualMachineScaleSets/jm-website-script-4-master-vmss/virtualMachines/1/networkInterfaces/jm-website-script-4-master-nic/ipConfigurations/jm-website-script-4-master-ip",
"etag": "W/\"09be80d2-76f5-49fc-ad47-0ef836a3799a\"",
"properties": {
"provisioningState": "Succeeded",
"privateIPAddress": "10.0.0.5",
...
So I tried to add to the variables:
"masterVM": "[concat('Microsoft.Compute/virtualMachineScaleSets/jm-website-script-4-master-vmss/virtualMachines/1/networkInterfaces/jm-website-script-4-master-nic/ipConfigurations/jm-website-script-4-master-ip')]",
And then call in outputs:
"outputs": {
"MasterFirstIPConfig": {
"type": "string",
"value": "[reference(variables('masterVM').properties.privateIPAddress)]"
}
}
Which returns me an error:
The language expression property 'Microsoft.WindowsAzure.ResourceStack.Frontdoor.Expression.Expressions.JTokenExpression' can't be evaluated..
I guess something is completely wrong with my masterVM variable definition here, but can't get it.
UPD The solution
Thanks for the answer by 4c74356b41.
The solution looks like next:
variable definition:
"masterVM": "Microsoft.Compute/virtualMachineScaleSets/jm-website-script-4-master-vmss/virtualMachines/1/networkInterfaces/jm-website-script-4-master-nic"
outputs:
"outputs": {
"MasterFirstIPConfig": {
"type": "string",
"value": "[reference(variables('masterVM'),'2016-09-01').ipConfigurations[0].properties.privateIPAddress]"
}
}

Well, you are targeting the wrong resource. You should be targeting the networkInterface (and you don't need to concat in this case), you also have to reference it properly:
"masterVM": "Microsoft.Compute/virtualMachineScaleSets/jm-website-script-4-master-vmss/virtualMachines/1/networkInterfaces/jm-website-script-4-master-nic]"
And reference like so
"value": "[reference(variables('masterVM'),'2016-09-01').ipConfigurations[0].properties.privateIPAddress]"

Related

How to reference Keyvault Secret Tags from ARM template

I have an ARM template which syncs secret value from source Keyvault into Destination one.
I also want to sync secret tags, but ARM reference that I use for 'sourceKV.secret.tags' retrieval does not work
[reference(resourceId('subscriptionId', 'resourceGroup', 'Microsoft.KeyVault/vaults/secrets', 'SourceKV', 'Secret'), '2021-04-01-preview', 'Full').tags.tagName]
any ideas what can be the issue, or what is the correct form to retrieve tags during ARM template deployment?
These work for me:
"outputs": {
"tags": {
"type": "string",
"value": "[reference('/subscriptions/xxxx/resourceGroups/yyyy/providers/Microsoft.KeyVault/vaults/zzzz/secrets/mysecret', '2022-07-01', 'Full').tags]"
},
"tagValue": {
"type": "string",
"value": "[reference('/subscriptions/xxxx/resourceGroups/yyyy/providers/Microsoft.KeyVault/vaults/zzzz/secrets/mysecret', '2022-07-01', 'Full').tags.hello]"
},
"tagValue2": {
"type": "string",
"value": "[reference(resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.KeyVault/vaults/secrets', 'xxxx', 'mysecret'), '2021-04-01-preview', 'Full').tags.hello]"
}
}
Will result in:
"outputs": {
"tagValue": {
"type": "String",
"value": "world"
},
"tagValue2": {
"type": "String",
"value": "world"
},
"tags": {
"type": "Object",
"value": {
"hello": "world"
}
}
}
Also works with the API version you used. It is important that you use 'Full', otherwise you won't get the tags. Note that you can use this syntax anywhere in your template. I just used it in the outputs because it is good for testing.
As I found out it is not possible to use Reference function for setting tags property value for keyvault as valid usages state
reference func only works if it is used inside properties block or for outputs; but as tags are not part of properties instead of returning value reference fun returns just string "reference(resource...)"

applicationGatewayBackendAddressPools configurations does not apply in virtual machine scale set

I have a VMSS which I deployed using ARM templates. This is the networkProfile block under VMSS resource section.
"networkProfile": {
"networkInterfaceConfigurations": [
{
"name": "[variables('nicName')]",
"properties": {
"primary": true,
"ipConfigurations": [
{
"name": "[concat(variables('VMSSName'), '-ipconfig')]",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},
"applicationGatewayBackendAddressPools": "[variables('AppGatewayBackendAddressPool')]"
}
}
]
}
}
]
},
In Variable section, if I use resourceId() function and provide values from parameters then it does not apply the configuration in VMSS. for example:
"AppGatewayBackendAddressPool": "[resourceId(parameters('VirtualNetworkResourceGroup'),'Microsoft.Network/applicationGateways/backendAddressPools', parameters('ApplicationGatewayName'), parameters('BackendAddressPool'))]",
I've also tried adding parameters('SubscriptionName') but the result is same.
"AppGatewayBackendAddressPool": "[resourceId(parameters('SubscriptionName') ,parameters('VirtualNetworkResourceGroup'),'Microsoft.Network/applicationGateways/backendAddressPools', parameters('ApplicationGatewayName'), parameters('BackendAddressPool'))]",
When I declare variable like below then it applies backendAddressPool configuration in Networking -> Load Balancing.
"AppGatewayBackendAddressPool": [
{ "id": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Network/applicationGateways/<applicationGatewayName>/backendAddressPools/<backendAddressPool>" }
],
Similar I'm doing with subnetRef like below and that is working fine.
"subnetRef": "[resourceId(parameters('VirtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks/subnets', parameters('VirtualNetworkName'), parameters('SubnetName'))]",
I want to parametrize the deployment by defining separate parameters.json file so I can attach applicationGatewayBackendAddressPools with different virtual machine scale sets.
This is how I achieved it by following Ked Mardemootoo answer.
IP configuration section under networkProfile of VMSS resource.
"ipConfigurations": [
{
"name": "[concat(variables('VMSSName'), '-ipconfig')]",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},
"applicationGatewayBackendAddressPools": [
{ "id": "[concat(parameters('AapplicationGatewayExternalid'), '/backendAddressPools/', parameters('BackendAddressPool'))]" }
]
}
}
]
Template file parameters:
"BackendAddressPool": {
"type": "string",
"metadata": {
"description": "Backend pool to host blue/green vmss."
}
},
"AapplicationGatewayExternalid": {
"type": "string",
"metadata": {
"description": "Application Gateway Id."
}
}
Now, ARM template is calling and referencing applicationGatewayBackendAddressPools attribute dynamically under VMSS' resource section.
I have these two parameters in parameters.json file where I can define values according to environment.
"BackendAddressPool": {
"value": "<backendPoolName>"
},
"AapplicationGatewayExternalid": {
"value": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Network/applicationGateways/<ApplicationGatewayName>"
}
Overriding template variables in release pipeline vars:
overriding template vars
Defining in pipeline vars
pipeline var
You seem to be missing the concat in the variables. Looking at the raw json on my end, this is how it's configured. See if you can do something similar, and convert the subnet name and backend address pool to variables.
"ipConfigurations": [
{
"name": "ip-vmss-name",
"properties": {
"primary": true,
"subnet": {
"id": "[concat(parameters('virtualNetworks_vnet_externalid'), '/subnets/snet-vm')]"
},
"privateIPAddressVersion": "IPv4",
"applicationGatewayBackendAddressPools": [
{
"id": "[concat(parameters('applicationGateways_agw_1_externalid'), '/backendAddressPools/be-addr-pool-vmss-1')]"
}
]
}
}
]
Nothing seems wrong with your variables/parameters call but applicationGatewayBackendAddressPools is not a valid attribute for neither VMSS nor Application Gateway.
You can do it check AKS and Application Gateway documentations. I achieve the same goal by setting backendAddressPools, which is in Application Gateway section, in different parameters.json files.

Why can I not access some fields of a publicIpAddress in template output?

In my template output, I'd like to return the allocated public IP address.
I tried the following in the "outputs" section: (in an output of 'object' type)
"ipobj": "[reference(variables('publicIPAddressName'),'2020-07-01','Full')]"
This works and returns the whole publicIpAddress object:
"ipobj": {
"apiVersion": "2020-07-01",
"location": "eastus",
"sku": {
"name": "Basic",
"tier": "Regional"
},
"properties": {
"provisioningState": "Succeeded",
"resourceGuid": "...",
"ipAddress": "...",
"publicIPAddressVersion": "IPv4",
"publicIPAllocationMethod": "Dynamic",
"idleTimeoutInMinutes": 4,
"dnsSettings": {
"domainNameLabel": "simplelinuxvm-zktwk4fzmy5p4",
"fqdn": "simplelinuxvm-zktwk4fzmy5p4.eastus.cloudapp.azure.com"
},
"ipTags": [],
"ipConfiguration": {
"id": "/subscriptions/.../resourceGroups/.../providers/Microsoft.Network/networkInterfaces/simpleLinuxVMNetInt/ipConfigurations/ipconfig1"
}
},
"subscriptionId": "...",
"resourceGroupName": "...",
"scope": "",
"resourceId": "Microsoft.Network/publicIpAddresses/simpleLinuxVMPublicIP",
"referenceApiVersion": "2020-07-01",
"condition": true,
"isConditionTrue": true,
"isTemplateResource": false,
"isAction": false,
"provisioningOperation": "Read"
}
This is in line with the API documentation of the publicIpAddress object.
And I can retrieve some of the properties as well, using the reference without the 'Full' parameter, which, according to the Azure doc, should return the properties of the object.
These work:
"[reference(variables('publicIPAddressName')).dnsSettings.fqdn]"
"[reference(variables('publicIPAddressName')).publicIPAddressVersion]"
But some other properties are not accessible:
"[reference(variables('publicIPAddressName')).ipAddress]"
"[reference(variables('publicIPAddressName'),'2020-07-01','Full').properties.ipAddress]"
According to the error message, (in case of the middle example):
The template output '...' is not valid: The language expression property 'ipAddress' doesn't exist, available properties are 'provisioningState, resourceGuid, publicIPAddressVersion, publicIPAllocationMethod, idleTimeoutInMinutes, dnsSettings, ipTags'
So it seems like Azure doesn't let me access the properties which are however there in the full output.
Is there any explanation/intention behind that, or a workaround at least ?
Note: the same happens if I define a "string" output (i.e. not as part of an object) as
"ip": {
"type": "string",
"value": "[reference(variables('publicIPAddressName')).ipAddress]"
}
or
"ip": {
"type": "string",
"value": "[reference(variables('publicIPAddressName'),'2020-07-01','Full').properties.ipAddress]"
},
I faced similar issue recently, and below are some of the references where the reason for this scenario is mentioned.
According to this:
i)
The 'ipaddress' property only exists if the 'publicIPAllocationMethod'
is set to 'Static'. ( A Static Public IP Address). If you did this on
an IP Address that was not static, it would return an error, but work
for those that were static.
ii)
It will only have the 'ipAddress' Property when attached to a service
or VM which is running. If the VM is 'Stopped', it will not have the
ipAddress property.
And, looks like there is an open issue in github in this link, related to this. Refer to this, in case it gets resolved in the future.
Check this link as well, where it is mentioned that:
This is a known limitation in the platform where a dynamic public IP
address doesn't resolve itself until the VM is up and running. There
are two options to workaround:
i) Create the Public IP Address in static mode. That will ensure that
Public IP address is immediately allocated. However, note that you
might incur additional charges.
ii) Change the dependency from Public IP address to the Virtual Machine
that the IP address is attached to. This will ensure that the public
IP address is always available.
When you output the properties of publicIpAddress object, you should pay attention to define the correct type that matches the output value.
"outputs": {
"publicIpipAddress": {
"type": "string",
"value": "[reference(parameters('publicIPAddresses_vmc_backupPublicIP_name'),'2020-07-01','Full').properties.ipAddress]"
},
"idleTimeoutInMinutes": {
"type": "int",
"value": "[reference(parameters('publicIPAddresses_vmc_backupPublicIP_name'),'2020-07-01','Full').properties.idleTimeoutInMinutes]"
}
}

arm template virtualNetworkName creation appendix issue

I am trying to get a arm template running and have hit an issue with the virtualnetwork creation.
azuredeploy.json
"virtualNetworkName": {
"type": "string",
"metadata": {
"description": "Name of virtual network to be created"
},
"defaultValue": "autohav2VNET"
},
vnet-net.json
"resources": [
{
"name": "[parameters('virtualNetworkName')]",
"type": "Microsoft.Network/virtualNetworks",
"location": "[parameters('location')]",
"apiVersion": "2015-06-15",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('virtualNetworkAddressRange')]"
]
},
"subnets": "[parameters('subnets')]"
}
}
]
The issue I am getting is that the vnet gets created with an appendix such as this: autohav2VNETl5g
So when this gets used to create a loadblancer, the names doe not match the defined parameter and the creation fails.
..../virtualNetworks/AUTOHAV2VNET referenced by resource .... /Microsoft.Network/loadBalancers/sqlLoadBalancer was not found.
Any suggestions?
with the data given it impossible to be sure why this is happening. you are probably passing in a value to the parameter virtualNetworkName. because if you wouldn't, than the vnet name would be: autohav2VNET.
ARM templates do not append anything anywhere just because they are arm templates. they only do what you designed them to do.
to help with debugging: how you are invoking the template and full template + full parameters file.

Azure: Cannot use output from Linked Template in IF condition

I'm trying to deploy a Virtual network using ARM template with multiple subnets. I have a linked template which creates NSGs,route table and assigns it to a specific subnet. I'm using copy to create multiple subnets. Route table should be assigned to only one particular subnet. I control this using If condition. The issue here is i'm not able to use the linked template output in the If condition. It fails with below error.
'{
"error": {
"code": "InvalidTemplate",
"message": "Unable to process template language expressions for resource
'/subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks/' at line '143' and column '9'. 'The provided
arguments for template language function 'if' is not valid: all arguments should be of type 'boolean'. Please see https://aka.ms/arm-template-expressions#if for usage details.'"
}
}'
Main Template (Subnet Creation snippet):-
"copy": [
{
"name": "subnets",
"count": "[length(parameters('subnetList'))]",
"input": {
"name": "[parameters('subnetList')[copyIndex('subnets')].name]",
"properties": {
"addressPrefix": "[parameters('subnetList')[copyIndex('subnets')].addressprefix]",
"networkSecurityGroup": "[if(equals(parameters('subnetList')[copyIndex('subnets')].name, 'GatewaySubnet'), json('null'), variables('nsgId'))]",
"routeTable": "[if(bool(parameters('subnetList')[copyIndex('subnets')].useRouteTable), reference('routeTableDeployment').outputs.resourceID.value, json('null'))]"
}
}
}
]
Route Table (Output snippet):-
"outputs": {
"resourceID": {
"type": "object",
"value": {
"id": "[resourceId('Microsoft.Network/routeTables', variables('routeTableName')]"
}
}
}
It works if I define a variable and pass it to if condition similar to nsg as below:-
"routeTableId": {
"id": "[resourceId('Microsoft.Network/routeTables', 'routeTableName')]"
}
"routeTable": "[if(bool(parameters('subnetList')[copyIndex('subnets')].useRouteTable), variables('routeTableId'), json('null'))]"

Resources