[英]ARM Template - auto approval of managed private endpoint
I am developing an ARM template for Azure Data Factory with managed private endpoints to SQL Server and Azure Datalake. 但是,當 ARM 模板完成執行時,托管專用端點處於“待定”state 中。 如何配置托管專用端點,以便在使用 ARM 模板完全配置 ADF 后將其配置為“已批准”。 以下是我的 template.json 文件:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environment": {
"type": "string",
"metadata": {
"description": "name of environment for deployment"
}
},
"project": {
"type": "string",
"metadata": {
"description": "name of the project for building the name of resources"
}
},
"location": {
"defaultValue": "eastus",
"type": "string"
},
"adfFactoryName": {
"type": "string"
},
"adfVersion": {
"type": "string"
},
"tags": {
"type": "object",
"metadata": {
"description": "tags to add to resources"
}
},
"adfVNetEnabled": {
"type": "bool"
},
"adfPublicNetworkAccess": {
"type": "bool"
},
"adfAzureDatabricksDomain": {
"type": "string",
"metadata": "Azure Databricks existing cluster Id"
},
"adfAzureDatabricksExistingClusterId": {
"type": "string",
"metadata": "Azure Databricks existing cluster Id"
},
"adfDataLakeConnectionString": {
"type": "string",
"metadata": "Azure Data Lake connection string"
},
"adfDataFactoryIdentity": {
"type": "string",
"metadata": "Identity type for data factory"
},
"adfLSASDBConnectionString": {
"type": "string",
"metadata": "SQL DB connection string"
},
"adfKVBaseURL": {
"type": "string",
"metadata": "Keyvault connection string"
},
"adfDataLakeStorageName": {
"type": "string",
"metadata": "Azure Data lake Storage Name"
},
"adfDataLakeStorageGroupId": {
"type": "string",
"metadata": "Azure Data lake Storage Group ID"
},
"adfSqlServerName": {
"type": "string",
"metadata": "Azure SQL Server name"
},
"adfSqlServerGroupId": {
"type": "string",
"metadata": "Azure SQL Server Group ID"
}
},
"variables": {
"factoryId": "[concat('Microsoft.DataFactory/factories/', parameters('adfFactoryName'))]",
"managedVirtualNetworkName": "[concat(parameters('adfFactoryName'), '/default')]"
},
"resources": [
{
"condition": "[equals(parameters('adfVersion'), 'V2')]",
"type": "Microsoft.DataFactory/factories",
"apiVersion": "2018-06-01",
"name": "[parameters('adfFactoryName')]",
"location": "[parameters('location')]",
"identity": {
"type": "[parameters('adfDataFactoryIdentity')]"
},
"properties": {
"publicNetworkAccess": "[if(bool(parameters('adfPublicNetworkAccess')), 'Enabled', 'Disabled')]"
},
"tags": "[parameters('tags')]",
"resources": [
{
"condition": "[and(equals(parameters('adfVersion'), 'V2'), parameters('adfVNetEnabled'))]",
"name": "[concat(parameters('adfFactoryName'), '/default')]",
"type": "Microsoft.DataFactory/factories/managedVirtualNetworks",
"apiVersion": "2018-06-01",
"properties": {},
"dependsOn": [
"[concat('Microsoft.DataFactory/factories/', parameters('adfFactoryName'))]"
]
},
{
"condition": "[and(equals(parameters('adfVersion'), 'V2'), parameters('adfVNetEnabled'))]",
"name": "[concat(parameters('adfFactoryName'), '/DDIR')]",
"type": "Microsoft.DataFactory/factories/integrationRuntimes",
"apiVersion": "2018-06-01",
"properties": {
"type": "Managed",
"managedVirtualNetwork": {
"referenceName": "default",
"type": "ManagedVirtualNetworkReference"
},
"typeProperties": {
"computeProperties": {
"location": "[parameters('location')]"
}
}
},
"dependsOn": [
"[concat('Microsoft.DataFactory/factories/', parameters('adfFactoryName'))]",
"[concat('Microsoft.DataFactory/factories/', parameters('adfFactoryName'), '/managedVirtualNetworks/default')]"
]
},
{
"name": "[concat(parameters('adfFactoryName'), '/AzureKeyVault')]",
"type": "Microsoft.DataFactory/factories/linkedServices",
"apiVersion": "2018-06-01",
"properties": {
"annotations": [],
"type": "AzureKeyVault",
"typeProperties": {
"baseUrl": "[parameters('adfKVBaseURL')]"
}
},
"dependsOn": [
"[parameters('adfFactoryName')]"
]
},
{
"name": "[concat(parameters('adfFactoryName'), '/AzureDatabricks_LinkedService')]",
"type": "Microsoft.DataFactory/factories/linkedServices",
"apiVersion": "2018-06-01",
"properties": {
"annotations": [],
"type": "AzureDatabricks",
"typeProperties": {
"domain": "[parameters('adfAzureDatabricksDomain')]",
"accessToken": {
"type": "AzureKeyVaultSecret",
"store": {
"referenceName": "AzureKeyVault",
"type": "LinkedServiceReference"
},
"secretName": "[concat('kvs-databricks-',parameters('environment'), 'aue', parameters('project'))]"
},
"existingClusterId": "[parameters('adfAzureDatabricksExistingClusterId')]"
},
"connectVia": {
"referenceName": "DDIR",
"type": "IntegrationRuntimeReference"
}
},
"dependsOn": [
"[parameters('adfFactoryName')]",
"[concat(variables('factoryId'), '/integrationRuntimes/DDIR')]",
"[concat(variables('factoryId'), '/linkedServices/AzureKeyVault')]"
]
},
{
"name": "[concat(parameters('adfFactoryName'), '/AzureDatalake_DDIR')]",
"type": "Microsoft.DataFactory/factories/linkedServices",
"apiVersion": "2018-06-01",
"properties": {
"annotations": [],
"type": "AzureBlobFS",
"typeProperties": {
"url": "[parameters('adfDataLakeConnectionString')]"
},
"connectVia": {
"referenceName": "DDIR",
"type": "IntegrationRuntimeReference"
}
},
"dependsOn": [
"[parameters('adfFactoryName')]",
"[concat(variables('factoryId'), '/integrationRuntimes/DDIR')]"
]
},
{
"name": "[concat(parameters('adfFactoryName'), '/LS_ASDB')]",
"type": "Microsoft.DataFactory/factories/linkedServices",
"apiVersion": "2018-06-01",
"properties": {
"annotations": [],
"type": "AzureSqlDatabase",
"typeProperties": {
"connectionString": "[parameters('adfLSASDBConnectionString')]",
"password": {
"type": "AzureKeyVaultSecret",
"store": {
"referenceName": "AzureKeyVault",
"type": "LinkedServiceReference"
},
"secretName": "kvs-synapsepwd-devauegteng"
}
},
"connectVia": {
"referenceName": "DDIR",
"type": "IntegrationRuntimeReference"
}
},
"dependsOn": [
"[parameters('adfFactoryName')]",
"[concat(variables('factoryId'), '/integrationRuntimes/DDIR')]",
"[concat(variables('factoryId'), '/linkedServices/AzureKeyVault')]"
]
}
]
},
{
"name": "[concat(parameters('adfFactoryName'), '/default/',parameters('adfDataLakeStorageName'))]",
"type": "Microsoft.DataFactory/factories/managedVirtualNetworks/managedPrivateEndpoints",
"apiVersion": "2018-06-01",
"properties": {
"privateLinkResourceId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('adfDataLakeStorageName'))]",
"groupId": "[parameters('adfDataLakeStorageGroupId')]"
},
"dependsOn": [
"[concat('Microsoft.DataFactory/factories/', parameters('adfFactoryName'), '/managedVirtualNetworks/default')]"
]
},
{
"name": "[concat(parameters('adfFactoryName'), '/default/',parameters('adfSqlServerName'))]",
"type": "Microsoft.DataFactory/factories/managedVirtualNetworks/managedPrivateEndpoints",
"apiVersion": "2018-06-01",
"properties": {
"privateLinkResourceId": "[resourceId('Microsoft.Sql/servers', parameters('adfSqlServerName'))]",
"groupId": "[parameters('adfSqlServerGroupId')]"
},
"dependsOn": [
"[concat('Microsoft.DataFactory/factories/', parameters('adfFactoryName'), '/managedVirtualNetworks/default')]"
]
}
]
}
使用Azure 門戶或使用帶有以下 JSON 模板的 ARM 模板創建私有終結點資源,並在 ConnectionState 中提及狀態為已批准。
例子:
{ "name": "string", "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2020-07-01", "location": "string", "tags": {}, "properties": { "subnet": { "id": "string", "name": "string" }, "privateLinkServiceConnections": [ { "id": "string", "properties": { "privateLinkServiceId": "string", "groupIds": [ "string" ], "requestMessage": "string", "privateLinkServiceConnectionState": { "status": "string", "description": "string", "actionsRequired": "string" } }, "name": "string" } ], "manualPrivateLinkServiceConnections": [ { "id": "string", "properties": { "privateLinkServiceId": "string", "groupIds": [ "string" ], "requestMessage": "string", "privateLinkServiceConnectionState": { "status": "string", "description": "string", "actionsRequired": "string" } }, "name": "string" } ], "customDnsConfigs": [ { "fqdn": "string", "ipAddresses": [ "string" ] } ] }, "resources": [] }
請參閱 - 字符串屬性值的私有端點。
我找不到在 ARM 本身中完成它的方法。 我的感覺是,如果可能的話,您必須處於鏈接的接收方(存儲帳戶、數據庫等),無論是 ARM、Bicep 還是 CLI。
我們現在正在做的是:
az network private-endpoint-connection list -g <RESOURCE_GROUP> -n <SA_NAME> --type Microsoft.Storage/storageAccounts --query "[?properties.privateLinkServiceConnectionState.status == 'Pending'].name" > output.json
jq -c '.[]' output.json | xargs -r -L 1 az network private-endpoint-connection approve -g <RESOURCE_GROUP> --resource-name <SA_NAME> --type Microsoft.Storage/storageAccounts --description "Approved" -n
您可以將其放在發布管道的Azure CLI步驟中。
我遇到了同樣的問題並創建了一個 Az Powershell 腳本函數來幫助我。
function ApprovePrivateEndpointConnections {
param (
[string] $ResourceGroupName,
[string] $ResourceName
)
$Resource = Get-AzResource -Name $ResourceName -ResourceGroupName $ResourceGroup
if ($Resource) {
$ResourcePendingConnection = Get-AzPrivateEndpointConnection -PrivatelinkResourceId $Resource.ResourceId | Where-Object -FilterScript {$_.PrivateLinkServiceConnectionState.Status -EQ 'Pending'}
if ($ResourcePendingConnection) {
foreach ($Connection in $ResourcePendingConnection)
{
Approve-AzPrivateEndpointConnection -ResourceId $Connection.Id
}
}
else
{
Write-Output 'No pending connections for Resource: ' $ResourceName
}
}
else
{
Write-Output 'No resource found with name: ' $ResourceName
}
}
我發現 Toofle 的腳本在這里是一個很好的開始,但對簡單地批准所有未決請求的安全風險感到有點緊張。
因此,我修改了腳本以獲取與我期望的私有端點相關的附加參數,並忽略任何不匹配的端點。
param(
[Parameter(Mandatory)]
[string] $DataFactoryName,
[Parameter(Mandatory)]
[string] $PrivateEndpointName,
[Parameter(Mandatory)]
[string] $TargetResourceId
)
$Resource = Get-AzResource -ResourceId $TargetResourceId
if ($Resource) {
$ResourcePendingConnection = Get-AzPrivateEndpointConnection -PrivatelinkResourceId $Resource.ResourceId `
| Where-Object -FilterScript {$_.PrivateLinkServiceConnectionState.Status -EQ 'Pending'} `
| Where-Object -FilterScript {$_.PrivateEndpoint.Id -like "*/providers/Microsoft.Network/privateEndpoints/$DataFactoryName.$PrivateEndpointName"}
if ($ResourcePendingConnection) {
foreach ($Connection in $ResourcePendingConnection)
{
Approve-AzPrivateEndpointConnection -ResourceId $Connection.Id
}
}
else
{
Write-Output 'No pending connections for Resource: ' $TargetResourceId
}
}
else
{
Write-Output 'No resource found with ID: ' $TargetResourceId
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.