Deploying a private endpoint and need the private ip address as output, but cannot seem to get value query right. Below results in "The template output 'hostname' is not valid: The language expression property | 'privateIPAddress' has an invalid array index.. (Code:DeploymentOutputEvaluationFailed)
"value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('privateEndpointName'))).networkInterfaces.privateIPAddress]"
Any idea of how to achieve this?
CodePudding user response:
Yes, I am able to obtain the private IP address associated with the private endpoint and it looks a bit convoluted due to having to work around some difficulties in Azure.
The first difficulty is that you cannot directly get at the properties of the child resource .networkInterfaces
from the perspective of the provider Microsoft.Network/privateEndpoints
. The reference will only provide the resource ID for the network interface.
The second difficulty is that one cannot nest a call to reference()
inside another call to reference()
. Azure resource management will report an error like "The template function 'reference' is not expected at this location.".
This will fail:
"value": "[reference(reference(resourceId('Microsoft.Network/privateEndpoints', parameters('privateEndpointName')), '2021-02-01').networkInterfaces[0].id, '2021-08-01').ipConfigurations[0].properties.privateIpAddress]"
The solution I have used is based on a collector pattern from the following page (https://docs.microsoft.com/en-us/azure/architecture/guide/azure-resource-manager/advanced-templates/collector#collector-template).
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"privateEndpointName": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-10-01",
"name": "nested",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"nicName": {
"value": "[last(split(reference(resourceId('Microsoft.Network/privateEndpoints', parameters('privateEndpointName')), '2021-08-01').networkInterfaces[0].id, '/'))]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"nicName": {
"type": "string"
}
},
"resources": [],
"outputs": {
"ip": {
"type": "string",
"value": "[reference(resourceId('Microsoft.Network/networkInterfaces', parameters('nicName')), '2021-08-01').ipConfigurations[0].properties.privateIPAddress]"
}
}
}
}
}
],
"outputs": {
"nicIpAddress": {
"type": "string",
"value": "[reference(resourceId('Microsoft.Resources/deployments', 'nested')).outputs.ip.value]"
}
}
}
Bonus I have a Bicep version the compiles to essentially the same JSON. I work primarily in Bicep these days.
main.bicep
param privateEndpointName string
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2021-08-01' existing = {
name: privateEndpointName
}
module networkInterface 'nested.bicep' = {
name: 'nested'
params: {
nicName: last(split(privateEndpoint.properties.networkInterfaces[0].id, '/'))
}
}
output nicIpAddress string = networkInterface.outputs.ip
nested.bicep
param nicName string
resource networkInterface 'Microsoft.Network/networkInterfaces@2021-08-01' existing = {
name: nicName
}
output ip string = networkInterface.properties.ipConfigurations[0].properties.privateIPAddress
CodePudding user response:
I have few private endpoints integrated with private DNS zone.
The private IP is available on the customDnsConfigs
property (Not a networking expert tho but it matches the network interface IP).
{
"value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('privateEndpointName')), '2021-08-01').customDnsConfigs[0].ipAddresses[0]]"
}