Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Con la versión 2023-08-01 de la API de recursos Microsoft.Resources/deploymentScripts, puede ejecutar scripts de implementación de manera privada en una instancia de Azure Container Instances (ACI).
Configuración del entorno
En esta configuración, la ACI creada por el script de implementación se ejecuta dentro de una red virtual y obtiene una dirección IP privada. A continuación, establece una conexión a una cuenta de almacenamiento nueva o preexistente a través de un punto de conexión privado. La propiedad containerSettings/subnetIds especifica la ACI que se debe implementar en una subred de la red virtual.
Para ejecutar scripts de implementación de forma privada, necesita la siguiente infraestructura como se muestra en el diagrama de arquitectura:
- Cree una red virtual con dos subredes:
- Una subred para el punto de conexión privado.
- Una subred para la ACI, esta subred necesita una delegación
Microsoft.ContainerInstance/containerGroups.
- Cree una cuenta de almacenamiento sin acceso a la red pública.
- Cree un punto de conexión privado dentro de la red virtual configurada con el subrecurso
fileen la cuenta de almacenamiento. - Cree una zona DNS privada
privatelink.file.core.windows.nety registre la dirección IP del punto de conexión privado como un registro A. Vincule la zona DNS privada a la red virtual creada. - Cree una identidad administrada asignada por el usuario con permisos
Storage File Data Privileged Contributoren la cuenta de almacenamiento y especifíquela en la propiedadidentityen el recurso de script de implementación. Para asignar la identidad, consulte Identidad. - El recurso ACI se crea automáticamente mediante el recurso de script de implementación.
Importante
Si asignas una identidad gestionada con permisos que superan los requisitos operativos del script, el autor del script es responsable de asegurar que la cuenta de almacenamiento esté protegida contra accesos no deseados. Siempre que sea posible, sigue el principio de menor privilegio.
El siguiente archivo de Bicep configura la infraestructura necesaria para ejecutar un script de implementación de forma privada:
@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@2025-01-31-preview' = {
name: userAssignedIdentityName
location: location
}
resource storageAccount 'Microsoft.Storage/storageAccounts@2025-06-01' = {
name: storageAccountName
kind: 'StorageV2'
location: location
sku: {
name: 'Standard_LRS'
}
properties: {
publicNetworkAccess: 'Disabled'
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
}
}
}
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2025-01-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@2024-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@2025-01-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: '14.0'
retentionInterval: 'P1D'
scriptContent: 'Write-Host "Hello World!"'
}
}
ACI descarga imágenes de contenedor de Microsoft Container Registry. Si usa un firewall, agregue la dirección URL mcr.microsoft.com a la lista de permitidos para descargar la imagen. Si no se puede descargar la imagen del contenedor, la ACI pasa a un estado de waiting, lo que finalmente provoca un error de tiempo de espera.
Pasos siguientes
En este artículo, ha aprendido a ejecutar scripts de implementación mediante un punto de conexión privado. Para obtener más información: