Privates Ausführen des Bicep-Bereitstellungsskripts über einen privaten Endpunkt
Mit der Microsoft.Resources/deploymentScripts
-Ressourcen-API-Version 2023-08-01
können Sie Bereitstellungsskripts privat in einer Azure-Containerinstanz (ACI) ausführen.
Konfigurieren der Umgebung
In diesem Setup wird die vom Bereitstellungsskript erstellte ACI in einem virtuellen Netzwerk ausgeführt und erhält eine private IP-Adresse. Anschließend stellt sie über einen privaten Endpunkt eine Verbindung mit einem neuen oder bereits vorhandenen Speicherkonto her. Die containerSettings/subnetIds
-Eigenschaft gibt die ACI an, die in einem Subnetz des virtuellen Netzwerks bereitgestellt werden muss.
Um Bereitstellungsskripts privat auszuführen, benötigen Sie die folgende Infrastruktur, wie im Architekturdiagramm dargestellt:
- Erstellen eines virtuellen Netzwerks mit zwei Subnetzen:
- Ein Subnetz für den privaten Endpunkt.
- Ein Subnetz für die ACI. Dieses Subnetz benötigt eine
Microsoft.ContainerInstance/containerGroups
-Delegierung.
- Erstellen Sie ein Speicherkonto mit öffentlichem Netzwerkzugriff.
- Erstellen Sie einen privaten Endpunkt innerhalb des virtuellen Netzwerks, der mit der
file
-Unterressource für das Speicherkonto konfiguriert ist. - Erstellen Sie die private DNS-Zone
privatelink.file.core.windows.net
, und registrieren Sie die IP-Adresse des privaten Endpunkts als A-Eintrag. Verknüpfen Sie die private DNS-Zone mit dem erstellten virtuellen Netzwerk. - Erstellen Sie eine benutzerseitig zugewiesene verwaltete Identität mit
Storage File Data Privileged Contributor
-Berechtigungen für das Speicherkonto, und geben Sie sie in deridentity
-Eigenschaft in der Bereitstellungsskriptressource an. Informationen zum Zuweisen der Identität finden Sie unter Identität. - Die ACI-Ressource wird automatisch von der Bereitstellungsskriptressource erstellt.
Die folgende Bicep-Datei konfiguriert die Infrastruktur, die für die private Ausführung eines Bereitstellungsskripts erforderlich ist:
@maxLength(10) // Required maximum length, because the storage account has a maximum of 26 characters
param namePrefix string
param location string = resourceGroup().location
param userAssignedIdentityName string = '${namePrefix}Identity'
param storageAccountName string = '${namePrefix}stg${uniqueString(resourceGroup().id)}'
param vnetName string = '${namePrefix}Vnet'
param deploymentScriptName string = '${namePrefix}ds'
var roleNameStorageFileDataPrivilegedContributor = '69566ab7-960f-475b-8e7c-b3118f30c6bd'
var vnetAddressPrefix = '192.168.4.0/23'
var subnetEndpointAddressPrefix = '192.168.4.0/24'
var subnetACIAddressPrefix = '192.168.5.0/24'
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: userAssignedIdentityName
location: location
}
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = {
name: storageAccountName
kind: 'StorageV2'
location: location
sku: {
name: 'Standard_LRS'
}
properties: {
publicNetworkAccess: 'Disabled'
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
}
}
}
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = {
name: storageAccount.name
location: location
properties: {
privateLinkServiceConnections: [
{
name: storageAccount.name
properties: {
privateLinkServiceId: storageAccount.id
groupIds: [
'file'
]
}
}
]
customNetworkInterfaceName: '${storageAccount.name}-nic'
subnet: {
id: virtualNetwork::privateEndpointSubnet.id
}
}
}
resource storageFileDataPrivilegedContributorReference 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
name: roleNameStorageFileDataPrivilegedContributor
scope: tenant()
}
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(storageFileDataPrivilegedContributorReference.id, managedIdentity.id, storageAccount.id)
scope: storageAccount
properties: {
principalId: managedIdentity.properties.principalId
roleDefinitionId: storageFileDataPrivilegedContributorReference.id
principalType: 'ServicePrincipal'
}
}
resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = {
name: 'privatelink.file.core.windows.net'
location: 'global'
resource virtualNetworkLink 'virtualNetworkLinks' = {
name: uniqueString(virtualNetwork.name)
location: 'global'
properties: {
registrationEnabled: false
virtualNetwork: {
id: virtualNetwork.id
}
}
}
resource resRecord 'A' = {
name: storageAccount.name
properties: {
ttl: 10
aRecords: [
{
ipv4Address: first(first(privateEndpoint.properties.customDnsConfigs)!.ipAddresses)
}
]
}
}
}
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-11-01' = {
name: vnetName
location: location
properties:{
addressSpace: {
addressPrefixes: [
vnetAddressPrefix
]
}
}
resource privateEndpointSubnet 'subnets' = {
name: 'PrivateEndpointSubnet'
properties: {
addressPrefixes: [
subnetEndpointAddressPrefix
]
}
}
resource containerInstanceSubnet 'subnets' = {
name: 'ContainerInstanceSubnet'
properties: {
addressPrefix: subnetACIAddressPrefix
delegations: [
{
name: 'containerDelegation'
properties: {
serviceName: 'Microsoft.ContainerInstance/containerGroups'
}
}
]
}
}
}
resource privateDeploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
name: deploymentScriptName
dependsOn: [
privateEndpoint
privateDnsZone::virtualNetworkLink
]
location: location
kind: 'AzurePowerShell'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${managedIdentity.id}' : {}
}
}
properties: {
storageAccountSettings: {
storageAccountName: storageAccount.name
}
containerSettings: {
subnetIds: [
{
id: virtualNetwork::containerInstanceSubnet.id
}
]
}
azPowerShellVersion: '9.0'
retentionInterval: 'P1D'
scriptContent: 'Write-Host "Hello World!"'
}
}
Die ACI lädt Containerimages aus der Microsoft-Containerregistrierung herunter. Wenn Sie eine Firewall verwenden, setzen Sie die URL mcr.microsoft.com zum Herunterladen des Images auf die Positivliste. Fehler beim Herunterladen des Containerimages führen dazu, dass die ACI in den Zustand waiting
versetzt wird, was schließlich zu einem Timeoutfehler führt.
Nächste Schritte
In diesem Artikel haben Sie erfahren, wie Sie Bereitstellungsskripts über einen privaten Endpunkt ausführen. Weitere Informationen: