How to automatically approve a private endpoint request from front door using bicep?

132 Views Asked by At

Implemented the answer from Thomas on this question: How do I automatically approve a private endpoint request from front door?

The bicep code seems to work accordingly but something strange is occurring. On the initial run where the link does not exist yet, it get's created as it should and is also approved, but the bicep deployment does fail on the approve step with the following message:

{
"status": "Failed",
"error": {
    "code": "ResourceDeploymentFailure",
    "target": "/subscriptions/<SUBID>/resourceGroups/<RGNAME>/providers/Microsoft.Web/sites/<APPNAME>/privateEndpointConnections/774ab459-37e5-4bb8-9bc5-436408c864c1-e54d42d7-34ce-42df-b09d-456031a9016d",
    "message": "The response for resource had empty or invalid content."
    }
}

As mentioned, it does approve the connection and when the exact same bicep code is run again, it results in a succeeded deployment.

Any ideas?

Reviewed the bicep templates and also the successful results when redeploying, nothing seems to be out of order.

As requested some code:

Part of the code to get the link and approve it, this is part of a template that first creates the origins.

module getPrivateLink 'private-link/web-getPrivateLink.bicep' = [for (origin, index) in originArray: if(contains(origin, 'privateLink') && privateLinkOriginDetails[index].groupId == 'sites'){
  name: 'getLink-${origin.name}'
  params: {
    name: origin.privateLink.privateLinkResourceName
  }
  dependsOn: [
    origins
  ]
}]

module approveLink 'private-link/web-approveLink.bicep' = [for (origin, index) in originArray: if(contains(origin, 'privateLink') && privateLinkOriginDetails[index].groupId == 'sites'){
  name: 'approveLink-${origin.name}'
  params: {
    appName: origin.privateLink.privateLinkResourceName
    linkName: getPrivateLink[index].outputs.linkName
  }
}]

web-GetPrivateLink.bicep

param name string

resource appService 'Microsoft.Web/sites@2022-09-01' existing = {
  name: name
}

output linkName string = last(split(first(appService.properties.privateEndpointConnections).id,'/'))
output resourceName string = name

web-approveLink.bicep

param appName string
param linkName string

resource appService 'Microsoft.Web/sites@2022-09-01' existing = {
  name: appName
}

resource privateEndpointConnection 'Microsoft.Web/sites/privateEndpointConnections@2022-09-01' = {
  parent: appService
  name: linkName
  properties: {
    privateLinkServiceConnectionState: {
      status: 'Approved'
      description: 'Approved by pipeline'
    }
  }
}

1

There are 1 best solutions below

5
Jahnavi On

By referring to the SO by @Thomas, I tried the similar approach to resolve your issue.

I was able to retrieve the connected private endpoint connection details with below CLI command as mentioned in the above reference.

az rest --method get --uri <appservice-resourceID>?api-version=xxxx

enter image description here

The displayed output contains the connection which I had in my app service.

Now coming to the bicep code, your code looks good to me. Need to check below to avoid little conflicts.

As mentioned in the Blog | @ Jeroen VdB, I got to know that when you are trying to link a endpoint which is presented in a virtual network (which was linked to the app service deployed), service endpoints have to be enabled under virtual networks resource.

"serviceEndpoints": [
                    {
                      "service": "Microsoft.Web"
                    }
            ]

Once it is enabled, I was able to deploy the resource successfully as shown below.

enter image description here

Alternatively, you can also add a resource deployment script to introduce and retrieve logs about delay before attempting to retrieve information about the approved connection.

Reference template: Microsoft.Resources/deployments