skip to Main Content

I am trying to create a private link to a Microsoft partner service in Azure using Powershell.

When I configure the endpoint through the Azure console, the segment of the template for the endpoint looks as follows:

{
    "type": "Microsoft.Network/privateEndpoints",
    "apiVersion": "2020-11-01",
    "name": "[parameters('privateEndpoints_foo_pl_silverfish_name')]",
    "location": "eastus2",
    "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworks_foo_pl_vnet_name'), 'foo_pl_subnet')]"
    ],
    "tags": {
        "owner": "foo"
    },
    "properties": {
        "privateLinkServiceConnections": [],
        "manualPrivateLinkServiceConnections": [
            {
                "name": "[parameters('privateEndpoints_foo_pl_silverfish_name')]",
                "properties": {
                    "privateLinkServiceId": "xyz-prod.67395a8a-a9d4-4c85-bd01-109a99e7eca2.eastus2.azure.privatelinkservice",
                    "groupIds": [],
                    "privateLinkServiceConnectionState": {
                        "status": "Approved"
                    }
                }
            }
        ],
        "subnet": {
            "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworks_foo_pl_vnet_name'), 'foo_pl_subnet')]"
        },
        "customDnsConfigs": []
    }
}

You can see the privateLinkServiceConnections array is empty. I’ve got content under the manualPrivateLinkServiceConnections array, which doesn’t conform to the options in the New-AzPrivateLinkServiceConnection commandlet.

This is with me creating the private endpoint through the console:

Create Private Endpoint in Console

Can I create a manual private link service connection with the New-AzPrivateLinkServiceConnection and New-AzPrivateEndpoint commandlets?

## Create the private link service configuration
$plink = New-AzPrivateLinkServiceConnection `
-Name 'foo_pl_silverfish_config' `
-PrivateLinkServiceId 'xyz-prod.67395a8a-a9d4-4c85-bd01-109a99e7eca2.eastus2.azure.privatelinkservice'

$privateEndpoint = New-AzPrivateEndpoint `
-ResourceGroupName 'foo_private_link' `
-Name 'foo_pl_db' `
-Location 'eastus2' `
-Subnet $sub `
-PrivateLinkServiceConnection $plink

I get the following error when running the above:

New-AzPrivateEndpoint: Operation returned an invalid status code 'BadRequest'
StatusCode: 400
ReasonPhrase: Bad Request
ErrorCode: LinkedInvalidPropertyId
ErrorMessage: Property id 'xyz-prod.67395a8a-a9d4-4c85-bd01-109a99e7eca2.eastus2.azure.privatelinkservice' at path 'properties.privateLinkServiceConnections[0].properties.privateLinkServiceId' is invalid. Expect fully qualified resource Id that start with '/subscriptions/{subscriptionId}' or '/providers/{resourceProviderNamespace}/'.

2

Answers


  1. Chosen as BEST ANSWER

    The only way I was able to build the private endpoint was using an ARM template that I deployed via Powershell script.

    The ARM template looks like the following:

    {
      "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "location": {
          "type": "string",
          "defaultValue": "[resourceGroup().location]",
          "metadata": {
            "description": "The location for resources created as part of the deployment."
          }
        },
        "virtualNetworkName": {
          "type": "string",
          "metadata": {
            "description": "The name of the virtual network hosting the private endpoint for the Astra private link."
          }
        },
        "privatelinkEndpointSubnetName": {
          "type": "string",
          "metadata": {
            "description": "The name of the subnet hosting the private endpoint."
          }
        },
        "privatelinkEndpointSubnetCIDR": {
          "type": "string",
          "metadata": {
            "description": "The CIDR range associated with the subnet hosting the private endpoint."
          }
        },
        "privateEndpointName": {
          "type": "string",
          "metadata": {
            "description": "The name of the private endpoint associated with the database's private link."
          }
        },
        "AstraDBServiceName": {
          "type": "string",
          "metadata": {
            "description": "The 'Service Name' for the subject Astra DB database."
          }
        }
      },
      "variables": {
        "PrivatelinkEndpointSubnetNameRef": "[concat(parameters('virtualNetworkName'), '/', parameters('privatelinkEndpointSubnetName'))]",
        "PrivatelinkEndpointSubnetIdRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('privatelinkEndpointSubnetName'))]"
      },
      "resources": [{
          "apiVersion": "2018-04-01",
          "type": "Microsoft.Network/virtualNetworks/subnets",
          "name": "[variables('PrivatelinkEndpointSubnetNameRef')]",
          "location": "[parameters('location')]",
          "properties": {
            "addressPrefix": "[concat(parameters('privatelinkEndpointSubnetCIDR'))]",
            "privateLinkServiceNetworkPolicies": "Disabled",
            "privateEndpointNetworkPolicies": "Disabled"
          }
        },
        {
          "dependsOn": [
            "[variables('PrivatelinkEndpointSubnetIdRef')]"
          ],
          "apiVersion": "2019-02-01",
          "type": "Microsoft.Network/privateEndpoints",
          "name": "[parameters('privateEndpointName')]",
          "location": "[parameters('location')]",
          "properties": {
            "manualPrivateLinkServiceConnections": [{
              "name": "{plsConnection}",
              "properties": {
                "privateLinkServiceId": "[parameters('AstraDBServiceName')]",
                "requestMessage": "Please approve my connection, thanks."
              }
            }],
            "subnet": {
              "id": "[variables('PrivatelinkEndpointSubnetIdRef')]"
            }
          }
        }
      ]
    }
    

    Here is the code I would use to build the template...

    $arm_template_parameters = @{
        'AstraDBServiceName'  = 'abc.593caf89-071c-4be7-f5ce9d3f9bc6
    .eastus.azure.privatelinkservice'
        'privateEndpointName' = 'myEndpoint'
        'virtualNetworkName'  = 'myVNET'
        'privatelinkEndpointSubnetName' = 'mySubnet'
        'privatelinkEndpointSubnetCIDR'  = '10.0.2.0/24'
    }
    
    New-AzResourceGroupDeployment `
        -Name 'myDeployment' `
        -ResourceGroupName 'myResourceGroup' `
        -TemplateFile '.template.json' `
        -TemplateParameterObject $arm_template_parameters `
        -verbose
    

    The problem for me is I ONLY have a resource id or alias. I can build from an ARM template or the Azure console. All the examples building the PE using Powershell require me to know the details about the service's load balancer, which I don't.


  2. ErrorMessage: Property id
    ‘xyz-prod.67395a8a-a9d4-4c85-bd01-109a99e7eca2.eastus2.azure.privatelinkservice’
    at path
    ‘properties.privateLinkServiceConnections[0].properties.privateLinkServiceId’
    is invalid. Expect fully qualified resource Id that start with
    ‘/subscriptions/{subscriptionId}’ or
    ‘/providers/{resourceProviderNamespace}/’.

    You need to pass the resourceId for the property PrivateLinkServiceId to the New-AzPrivateLinkServiceConnection cmdlet.

    Can I create a manual private link service connection with the
    New-AzPrivateLinkServiceConnection and New-AzPrivateEndpoint
    commandlets?

    Yes, you can create manualPrivateLinkServiceConnections using -ByManualRequest in the New-AzPrivateLinkServiceConnection powershell cmdlet.

    Here is the reference documentation for more information about the supported properties for the above cmdlet.

    I have tested this in my local environment by creating a private endpoint to storage table in one of the storage accounts in my subscription.

    Here is the cmdlet that I have used:

    $virtualNetwork = Get-AzVirtualNetwork -ResourceName '<VirtualNetworkName>' -ResourceGroupName '<resourceGroupName>'
    $subnet = $virtualNetwork | Select-Object -ExpandProperty subnets | Where-Object Name -eq '<SubnetName>'
    $plsConnection= New-AzPrivateLinkServiceConnection -Name '<PLSConnectionsName>' -PrivateLinkServiceId '<ResourceID to which resource you want to create endpoint connection>' -RequestMessage 'Please Approve my request' -GroupId 'queue'
    New-AzPrivateEndpoint -Name '<PrivateEndpointName>' -ResourceGroupName '<ResourceGroupName>' -Location 'eastus' -PrivateLinkServiceConnection $plsConnection -Subnet $subnet -ByManualRequest
    

    Here is the sample output for your reference:

    enter image description here


    Updated Answer:
    If you want to create the private endpoint using the private link service alias(foo..<azure_region>.azure.privatelinkservice) you can use the below powershell script.

    $virtualNetwork = Get-AzVirtualNetwork -ResourceName '<VirtualNetworkName>' -ResourceGroupName '<resourceGroupName>'
    $subnet = $virtualNetwork | Select-Object -ExpandProperty subnets | Where-Object Name -eq '<SubnetName>'
    $privatelinkAlias= Get-AzPrivateLinkService -Name '<privateServiceLinkName>' -ResourceGroupName '<resourceGroupName>'
    $plsConnection= New-AzPrivateLinkServiceConnection -Name '<PLSConnectionsName>' -PrivateLinkServiceId $privatelinkAlias.Alias -RequestMessage 'Please Approve my request'
    New-AzPrivateEndpoint -Name '<PrivateEndpointName>' -ResourceGroupName '<ResourceGroupName>' -Location 'eastus' -PrivateLinkServiceConnection $plsConnection -Subnet $subnet -ByManualRequest
    

    Here is the sample output screenshot:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search