Unable to rename or delete blob files via Azure VPN connection

Jason McReynolds 20 Reputation points
2024-08-09T21:06:51.16+00:00

I have several storage accounts and successfully configured an Azure point-to-site VPN connection to be able to connect to them. My initial test with Azure Storage Explorer only validated that you could browse the directories/files when connected via Azure VPN (point-to-site using Azure VPN Client), but later I found out that I cannot rename or delete files/directories (not authorized). However, I can upload new files and folders without any issue. Public network access for the storage account is "Enabled from selected virtual networks and IP addresses" and the box to "Allow Azure services on the trusted services list to access this storage account" is also checked (no public IPs are added as exceptions). Select virtual networks are also added. If I add my public IP address as an exception I can rename and delete files/directories. If I choose "Disabled" for public network access, the results are the same - I can still connect via VPN and browse files/directories using Azure Storage Explorer, but when I try to delete or rename a file/directory it fails.

I have private endpoints setup for the storage accounts and I configured a DNS private resolver. DNS correctly resolves to the private IP address when connected via VPN. I setup the Azure VPN clientconfig as follows, and it appears to be working correctly:

    <clientconfig>
        <dnssuffixes>
			<dnssuffix>.azurecr.io</dnssuffix>
            <dnssuffix>.azuredatabricks.net</dnssuffix>
            <dnssuffix>.azurestaticapps.net</dnssuffix>
            <dnssuffix>.1.azurestaticapps.net</dnssuffix>
            <dnssuffix>.2.azurestaticapps.net</dnssuffix>
            <dnssuffix>.azurewebsites.net</dnssuffix>
            <dnssuffix>.scm.azurewebsites.net</dnssuffix>
            <dnssuffix>.blob.core.windows.net</dnssuffix>
            <dnssuffix>.privatelink.blob.core.windows.net</dnssuffix>
            <dnssuffix>.database.windows.net</dnssuffix>
            <dnssuffix>.datafactory.azure.net</dnssuffix>
            <dnssuffix>.dfs.core.windows.net</dnssuffix>
            <dnssuffix>.file.core.windows.net</dnssuffix>
            <dnssuffix>.postgres.database.azure.com</dnssuffix>
            <dnssuffix>.vault.azure.net</dnssuffix>
            <dnssuffix>.vaultcore.azure.net</dnssuffix>
            <dnssuffix>.wvd.microsoft.com</dnssuffix>
            <dnssuffix>.azurecontainerapps.io</dnssuffix>
        </dnssuffixes>
        <dnsservers>
            <dnsserver>x.x.x.x</dnsserver>
        </dnsservers>
  </clientconfig>

In a nutshell, the error I get when I try to rename/delete is:

AuthorizationFailure - This request is not authorized to perform this operation.

I've included some lines from the Azure Storage Explorer error at the end, but the full error is over 6000 lines, most of it not really helpful.

I have the contributor role on the storage accounts, so permission should not be an issue, and if I add my IP address as a firewall exception it works as expected. I also tried adding a connection in Azure Storage Explorer, for a Storage account or service, using a SAS key (full permissions - all boxes checked), and the behavior was the same - I could browse, but not delete or rename. I'm running the newest version of Azure Storage Explorer (1.34.0 (99), AzCopy Version: 10.24.0) as of the posting of this issue.

Can anyone else successfully rename/delete files/directories when connected via VPN? Why isn't this working as expected? What have I missed? Is this a bug?

Thanks!

{
  "name": "RestError",
  "message": "This request is not authorized to perform this operation.\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\nTime:2024-08-09T20:07:56.5476270Z",
  "stack": "RestError: This request is not authorized to perform this operation.\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\nTime:2024-08-09T20:07:56.5476270Z\n    at handleErrorResponse (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:15:2973)\n    at C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:15:1827\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at async ll.attemptSendRequest (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:36:58311)\n    at async ml.sendOperationRequest (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:16:12049)\n    at async a.move (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:42:12256)\n    at async mc.runOperation (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:59:6274)\n    at async mc.movePath (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:106:16391)\n    at async renamePath (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:106:26156)\n    at async Azure.Storage.AdlsGen2.renamePath (C:\\Users\\usernamehere\\AppData\\Local\\Programs\\Microsoft Azure Storage Explorer\\resources\\app\\node_modules\\@storage-explorer\\adls2-extension\\dist\\src\\index.js:108:10482)",
  "code": "AuthorizationFailure",
  "statusCode": 403,
  "request": {
    "streamResponseStatusCodes": {},
    "url": "https://StorageAccountNameHere.dfs.core.windows.net/data/folder1/folder2/download_copy.svg?mode=legacy",
    "method": "PUT",
    "headers": {
      "_headersMap": {
        "accept": {
          "name": "Accept",
          "value": "application/json"
        },
        "x-ms-version": {
          "name": "x-ms-version",
          "value": "2023-11-03"
        },
        "x-ms-rename-source": {
          "name": "x-ms-rename-source",
          "value": "/data/folder1/folder2/download%20(2).svg"
        },
        "user-agent": {
          "name": "User-Agent",
          "value": "Microsoft Azure Storage Explorer/1.34.0 (win32) azsdk-js-storagedatalake/12.16.0 (NODE-VERSION v20.9.0; Windows_NT 10.0.22631)"
        },
        "x-ms-client-request-id": {
          "name": "x-ms-client-request-id",
          "value": "xxxxxx-xxxxxx-xxxxxx-xxxxxx"
        },
        "authorization": {
          "name": "authorization",
          "value": "Bearer JSON Web Token Redacted"
        }
      }
    },
    "withCredentials": false,
    "timeout": 0,
    "keepAlive": true,
    "decompressResponse": false,
    "requestId": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
    "operationSpec": {
      "path": "/{filesystem}/{path}",
      "httpMethod": "PUT",
      "responses": {
        "201": {
          "headersMapper": {
            "serializedName": "Path_createHeaders",
            "type": {
              "name": "Composite",
              "className": "PathCreateHeaders",
              "modelProperties": {
                "date": {
                  "serializedName": "date",
                  "xmlName": "date",
                  "type": {
                    "name": "DateTimeRfc1123"
                  }
                },
                "etag": {
                  "serializedName": "etag",
                  "xmlName": "etag",
                  "type": {
                    "name": "String"
                  }
                },
                "lastModified": {
                  "serializedName": "last-modified",
                  "xmlName": "last-modified",
                  "type": {
                    "name": "DateTimeRfc1123"
                  }
                },
                "requestId": {
                  "constraints": {
                    "Pattern": {}
                  },
                  "serializedName": "x-ms-request-id",
                  "xmlName": "x-ms-request-id",
                  "type": {
                    "name": "String"
                  }
                },
                "version": {
                  "serializedName": "x-ms-version",
                  "xmlName": "x-ms-version",
                  "type": {
                    "name": "String"
                  }
                },
                "continuation": {
                  "serializedName": "x-ms-continuation",
                  "xmlName": "x-ms-continuation",
                  "type": {
                    "name": "String"
                  }
                },
                "contentLength": {
                  "serializedName": "content-length",
                  "xmlName": "content-length",
                  "type": {
                    "name": "Number"
                  }
                },
                "isServerEncrypted": {
                  "serializedName": "x-ms-request-server-encrypted",
                  "xmlName": "x-ms-request-server-encrypted",
                  "type": {
                    "name": "Boolean"
                  }
                },
                "encryptionKeySha256": {
                  "serializedName": "x-ms-encryption-key-sha256",
                  "xmlName": "x-ms-encryption-key-sha256",
                  "type": {
                    "name": "String"
                  }
                },
                "errorCode": {
                  "serializedName": "x-ms-error-code",
                  "xmlName": "x-ms-error-code",
                  "type": {
                    "name": "String"
                  }
                }
              }
            }
          }
        },
        "default": {
          "bodyMapper": {
            "serializedName": "StorageError",
            "type": {
              "name": "Composite",
              "className": "StorageError",
              "modelProperties": {
                "error": {
                  "serializedName": "error",
                  "xmlName": "error",
                  "type": {
                    "name": "Composite",
                    "className": "StorageErrorError"
                  }
                },
                "code": {
                  "serializedName": "Code",
                  "xmlName": "Code",
                  "type": {
                    "name": "String"
                  }
                }
              }
            }
          },
          "headersMapper": {
            "serializedName": "Path_createExceptionHeaders",
            "type": {
              "name": "Composite",
              "className": "PathCreateExceptionHeaders",
              "modelProperties": {
                "errorCode": {
                  "serializedName": "x-ms-error-code",
                  "xmlName": "x-ms-error-code",
                  "type": {
                    "name": "String"
                  }
                }
              }
            }
          }
        }
      },
      "queryParameters": [
        {
          "parameterPath": [
            "options",
            "continuation"
          ],
          "mapper": {
            "serializedName": "continuation",
            "xmlName": "continuation",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "timeout"
          ],
          "mapper": {
            "constraints": {
              "InclusiveMinimum": 0
            },
            "serializedName": "timeout",
            "xmlName": "timeout",
            "type": {
              "name": "Number"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "resource"
          ],
          "mapper": {
            "serializedName": "resource",
            "xmlName": "resource",
            "type": {
              "name": "Enum",
              "allowedValues": [
                "directory",
                "file"
              ]
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "mode"
          ],
          "mapper": {
            "serializedName": "mode",
            "xmlName": "mode",
            "type": {
              "name": "Enum",
              "allowedValues": [
                "legacy",
                "posix"
              ]
            }
          }
        }
      ],
      "urlParameters": [
        {
          "parameterPath": "url",
          "mapper": {
            "serializedName": "url",
            "required": true,
            "xmlName": "url",
            "type": {
              "name": "String"
            }
          },
          "skipEncoding": true
        }
      ],
      "headerParameters": [
        {
          "parameterPath": "accept",
          "mapper": {
            "defaultValue": "application/json",
            "isConstant": true,
            "serializedName": "Accept",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "requestId"
          ],
          "mapper": {
            "serializedName": "x-ms-client-request-id",
            "xmlName": "x-ms-client-request-id",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": "version",
          "mapper": {
            "defaultValue": "2023-11-03",
            "isConstant": true,
            "serializedName": "x-ms-version",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "properties"
          ],
          "mapper": {
            "serializedName": "x-ms-properties",
            "xmlName": "x-ms-properties",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "modifiedAccessConditions",
            "ifModifiedSince"
          ],
          "mapper": {
            "serializedName": "If-Modified-Since",
            "xmlName": "If-Modified-Since",
            "type": {
              "name": "DateTimeRfc1123"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "modifiedAccessConditions",
            "ifUnmodifiedSince"
          ],
          "mapper": {
            "serializedName": "If-Unmodified-Since",
            "xmlName": "If-Unmodified-Since",
            "type": {
              "name": "DateTimeRfc1123"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "pathHttpHeaders",
            "cacheControl"
          ],
          "mapper": {
            "serializedName": "x-ms-cache-control",
            "xmlName": "x-ms-cache-control",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "pathHttpHeaders",
            "contentEncoding"
          ],
          "mapper": {
            "serializedName": "x-ms-content-encoding",
            "xmlName": "x-ms-content-encoding",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "pathHttpHeaders",
            "contentLanguage"
          ],
          "mapper": {
            "serializedName": "x-ms-content-language",
            "xmlName": "x-ms-content-language",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "pathHttpHeaders",
            "contentDisposition"
          ],
          "mapper": {
            "serializedName": "x-ms-content-disposition",
            "xmlName": "x-ms-content-disposition",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "pathHttpHeaders",
            "contentType"
          ],
          "mapper": {
            "serializedName": "x-ms-content-type",
            "xmlName": "x-ms-content-type",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "renameSource"
          ],
          "mapper": {
            "serializedName": "x-ms-rename-source",
            "xmlName": "x-ms-rename-source",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "leaseAccessConditions",
            "leaseId"
          ],
          "mapper": {
            "serializedName": "x-ms-lease-id",
            "xmlName": "x-ms-lease-id",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "sourceLeaseId"
          ],
          "mapper": {
            "serializedName": "x-ms-source-lease-id",
            "xmlName": "x-ms-source-lease-id",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "permissions"
          ],
          "mapper": {
            "serializedName": "x-ms-permissions",
            "xmlName": "x-ms-permissions",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "umask"
          ],
          "mapper": {
            "serializedName": "x-ms-umask",
            "xmlName": "x-ms-umask",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "modifiedAccessConditions",
            "ifMatch"
          ],
          "mapper": {
            "serializedName": "If-Match",
            "xmlName": "If-Match",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "modifiedAccessConditions",
            "ifNoneMatch"
          ],
          "mapper": {
            "serializedName": "If-None-Match",
            "xmlName": "If-None-Match",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "sourceModifiedAccessConditions",
            "sourceIfMatch"
          ],
          "mapper": {
            "serializedName": "x-ms-source-if-match",
            "xmlName": "x-ms-source-if-match",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "sourceModifiedAccessConditions",
            "sourceIfNoneMatch"
          ],
          "mapper": {
            "serializedName": "x-ms-source-if-none-match",
            "xmlName": "x-ms-source-if-none-match",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "sourceModifiedAccessConditions",
            "sourceIfModifiedSince"
          ],
          "mapper": {
            "serializedName": "x-ms-source-if-modified-since",
            "xmlName": "x-ms-source-if-modified-since",
            "type": {
              "name": "DateTimeRfc1123"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "sourceModifiedAccessConditions",
            "sourceIfUnmodifiedSince"
          ],
          "mapper": {
            "serializedName": "x-ms-source-if-unmodified-since",
            "xmlName": "x-ms-source-if-unmodified-since",
            "type": {
              "name": "DateTimeRfc1123"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "cpkInfo",
            "encryptionKey"
          ],
          "mapper": {
            "serializedName": "x-ms-encryption-key",
            "xmlName": "x-ms-encryption-key",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "cpkInfo",
            "encryptionKeySha256"
          ],
          "mapper": {
            "serializedName": "x-ms-encryption-key-sha256",
            "xmlName": "x-ms-encryption-key-sha256",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "cpkInfo",
            "encryptionAlgorithm"
          ],
          "mapper": {
            "serializedName": "x-ms-encryption-algorithm",
            "xmlName": "x-ms-encryption-algorithm",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "owner"
          ],
          "mapper": {
            "serializedName": "x-ms-owner",
            "xmlName": "x-ms-owner",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "group"
          ],
          "mapper": {
            "serializedName": "x-ms-group",
            "xmlName": "x-ms-group",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "acl"
          ],
          "mapper": {
            "serializedName": "x-ms-acl",
            "xmlName": "x-ms-acl",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "proposedLeaseId"
          ],
          "mapper": {
            "serializedName": "x-ms-proposed-lease-id",
            "xmlName": "x-ms-proposed-lease-id",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "leaseDuration"
          ],
          "mapper": {
            "serializedName": "x-ms-lease-duration",
            "xmlName": "x-ms-lease-duration",
            "type": {
              "name": "Number"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "expiryOptions"
          ],
          "mapper": {
            "serializedName": "x-ms-expiry-option",
            "xmlName": "x-ms-expiry-option",
            "type": {
              "name": "Enum",
              "allowedValues": [
                "NeverExpire",
                "RelativeToCreation",
                "RelativeToNow",
                "Absolute"
              ]
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "expiresOn"
          ],
          "mapper": {
            "serializedName": "x-ms-expiry-time",
            "xmlName": "x-ms-expiry-time",
            "type": {
              "name": "String"
            }
          }
        },
        {
          "parameterPath": [
            "options",
            "encryptionContext"
          ],
          "mapper": {
            "serializedName": "x-ms-encryption-context",
            "xmlName": "x-ms-encryption-context",
            "type": {
              "name": "String"
            }
          }
        }
      ],

...

  "response": {
    "request": {
      "streamResponseStatusCodes": {},
      "url": "https://StorageAccountNameHere.dfs.core.windows.net/data/folder1/folder2/download_copy.svg?mode=legacy",
      "method": "PUT",
      "headers": {
        "_headersMap": {
          "accept": {
            "name": "Accept",
            "value": "application/json"
          },
          "x-ms-version": {
            "name": "x-ms-version",
            "value": "2023-11-03"
          },
          "x-ms-rename-source": {
            "name": "x-ms-rename-source",
            "value": "/data/folder1/folder2/download%20(2).svg"
          },
          "user-agent": {
            "name": "User-Agent",
            "value": "Microsoft Azure Storage Explorer/1.34.0 (win32) azsdk-js-storagedatalake/12.16.0 (NODE-VERSION v20.9.0; Windows_NT 10.0.22631)"
          },
          "x-ms-client-request-id": {
            "name": "x-ms-client-request-id",
            "value": "xxxxxx-xxxxxx-xxxxxx-xxxxxx"
          },
          "authorization": {
            "name": "authorization",
            "value": "Bearer JSON Web Token Redacted"
          }
        }
      },

...

    "bodyAsText": "{\"error\":{\"code\":\"AuthorizationFailure\",\"message\":\"This request is not authorized to perform this operation.\\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\\nTime:2024-08-09T20:07:56.5476270Z\"}}",
    "parsedBody": {
      "error": {
        "code": "AuthorizationFailure",
        "message": "This request is not authorized to perform this operation.\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\nTime:2024-08-09T20:07:56.5476270Z"
      }
    },
    "parsedHeaders": {
      "errorCode": "AuthorizationFailure",
      "content-length": "194",
      "content-type": "application/json;charset=utf-8",
      "date": "Fri, 09 Aug 2024 20:07:55 GMT",
      "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0",
      "x-ms-client-request-id": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
      "x-ms-request-id": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
      "x-ms-version": "2023-11-03"
    }
  },
  "details": {
    "errorCode": "AuthorizationFailure",
    "content-length": "194",
    "content-type": "application/json;charset=utf-8",
    "date": "Fri, 09 Aug 2024 20:07:55 GMT",
    "server": "Windows-Azure-HDFS/1.0 Microsoft-HTTPAPI/2.0",
    "x-ms-client-request-id": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
    "x-ms-request-id": "xxxxxx-xxxxxx-xxxxxx-xxxxxx",
    "x-ms-version": "2023-11-03",
    "error": {
      "code": "AuthorizationFailure",
      "message": "This request is not authorized to perform this operation.\nRequestId:xxxxxx-xxxxxx-xxxxxx-xxxxxx\nTime:2024-08-09T20:07:56.5476270Z"
    }
  }
}
Azure Storage Explorer
Azure Storage Explorer
An Azure tool that is used to manage cloud storage resources on Windows, macOS, and Linux.
252 questions
Azure Storage Accounts
Azure Storage Accounts
Globally unique resources that provide access to data management services and serve as the parent namespace for the services.
3,105 questions
Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
2,787 questions
{count} votes

Accepted answer
  1. Nehruji R 7,306 Reputation points Microsoft Vendor
    2024-08-29T04:35:27.1933333+00:00

    Jason McReynolds, I'm glad that you were able to resolve your issue and thank you for posting your solution so that others experiencing the same thing can easily reference this!

    Since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others ", I'll repost your solution in case you'd like to "Accept " the answer. Accepted answers show up at the top, resulting in improved discoverability for others.

    Issue: Customer unable to rename or delete blob files via Azure VPN connection.

    Solution: The issue got mitigated, once added an additional private endpoint for the dfs sub-resource along with the one that had already added for the blob sub-resource. So, you need two private endpoints, one for blob and one for dfs, refer MS documentation here:

    If you create a private endpoint for the Data Lake Storage Gen2 storage resource, then you should also create one for the Blob Storage resource. That's because operations that target the Data Lake Storage Gen2 endpoint might be redirected to the Blob endpoint. Similarly, if you add a private endpoint for Blob Storage only, and not for Data Lake Storage Gen2, some operations (such as Manage ACL, Create Directory, Delete Directory, etc.) will fail since the Gen2 APIs require a DFS private endpoint. By creating a private endpoint for both resources, you ensure that all operations can complete successfully.

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Jason McReynolds 20 Reputation points
    2024-08-28T21:38:10.35+00:00

    I finally figured out why this wasn't working based on info found in this post. I needed to add an additional private endpoint for the dfs sub-resource along with the one that I had already added for the blob sub-resource. So, you need two private endpoints, one for blob and one for dfs. Not sure why I didn't figure this out sooner, it's pretty clear in the MS documentation here:

    If you create a private endpoint for the Data Lake Storage Gen2 storage resource, then you should also create one for the Blob Storage resource. That's because operations that target the Data Lake Storage Gen2 endpoint might be redirected to the Blob endpoint. Similarly, if you add a private endpoint for Blob Storage only, and not for Data Lake Storage Gen2, some operations (such as Manage ACL, Create Directory, Delete Directory, etc.) will fail since the Gen2 APIs require a DFS private endpoint. By creating a private endpoint for both resources, you ensure that all operations can complete successfully.

    0 comments No comments

  2. Nehruji R 7,306 Reputation points Microsoft Vendor
    2024-08-13T06:48:42.34+00:00

    Hello Jason McReynolds,

     

    Greetings! Welcome to Microsoft Q&A Platform.

      

    As per your above questions, I understand that you want to rename/delete without adding public IP addresses as exceptions, even if the user is connected via VPN, "Yes" it is possible but the VPN connection must be correctly established so that all traffic to the storage account is routed through the private endpoint and not through the public network paths. It is important that, Private endpoint should be properly set up for your Azure Storage Account, and it should be linked to the virtual network associated with your VPN and correctly configure your DNS settings to resolve the private endpoint IP address to the fully qualified domain name (FQDN) of the connection string.

     

    Existing Microsoft Azure services might already have a DNS configuration for a public endpoint. This configuration must be overridden to connect using your private endpoint. You can use "private DNS zones" to override the DNS resolution for a private endpoint. A private DNS zone can be linked to your virtual network to resolve specific domains.

     

    Azure creates a canonical name DNS record (CNAME) on the public DNS. The CNAME record redirects the resolution to the private domain name. You can override the resolution with the private IP address of your private endpoints. Connection URLs for your existing applications don't change. Client DNS requests to a public DNS server resolve to your private endpoints. The process doesn't affect your existing applications.

     

    Make sure that there is no network security groups (NSGs) or routing configurations that could block or misroute the traffic from your VPN to the private endpoint. The Azure Storage firewall provides access control for the public endpoint of your storage account. You can also use the firewall to block all access through the public endpoint when you're using private endpoints.

     

    A similar issue is discussed in the Answer section of the following SO thread: https://stackoverflow.com/questions/75931223/problem-when-trying-to-connect-to-blob-private-endpoint-in-azure-with-point-to-s#:~:text=Check%20the%20DNS%20settings%20on%20your%20computer%20to,looking%20at%20the%20routing%20tables%20on%20your%20computer.

     

    Here is the doc for your reference: https://video2.skills-academy.com/en-us/azure/private-link/private-endpoint-dns, https://video2.skills-academy.com/en-us/azure/storage/common/storage-network-security?tabs=azure-portal, https://video2.skills-academy.com/en-us/azure/private-link/tutorial-private-endpoint-storage-portal?tabs=dynamic-ip

     

    Hope this answer helps! please let us know if you have any further queries. I’m happy to assist you further.

    Please "Accept the answer” and “up-vote” wherever the information provided helps you, this can be beneficial to other community members


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.