簡體   English   中英

ARM 模板 - 托管專用端點的自動批准

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM