skip to Main Content

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?

2

Answers


  1. 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://learn.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
    
    Login or Signup to reply.
  2. 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]]"
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search