Accedere a una rete virtuale privata da uno script di distribuzione Bicep

Con Microsoft.Resources/deploymentScripts la versione 2023-08-01è possibile eseguire script di distribuzione in reti private con alcune configurazioni aggiuntive:

  • Creare un'identità gestita assegnata dall'utente e specificarla nella proprietà identity. Per assegnare l'identità, vedere Identità.

  • Creare un account di archiviazione nella rete privata e specificare lo script di distribuzione per usare l'account di archiviazione esistente. Per altre informazioni, vedere Usare un account di archiviazione esistente. Per l'account di archiviazione sono necessarie alcune configurazioni aggiuntive:

    Importante

    Se assegni un'identità gestita con permessi che superano i requisiti operativi dello script, l'autore dello script è responsabile di garantire che l'account di archiviazione sia protetto da accessi indesiderati. Dove possibile, segui il principio del minimo privilegio.

    1. Aprire l'account di archiviazione nel portale di Azure.
    2. Nel menu a sinistra selezionare Controllo di accesso (IAM) e quindi selezionare la scheda Assegnazioni di ruolo .
    3. Aggiungere il ruolo Collaboratore con privilegi per i dati dei file di archiviazione all'identità gestita assegnata dall'utente.
    4. Nel menu a sinistra, in Sicurezza e rete selezionare Rete e quindi Firewall e reti virtuali.
    5. Selezionare Abilitato da reti virtuali e indirizzi IP selezionati.
    6. In Reti virtuali, aggiungere una subnet. Nello screenshot seguente la subnet è denominata dspvnVnet.
    7. In Eccezioni, selezionare Consenti ai servizi di Azure nell'elenco dei servizi attendibili di accedere a questo account di archiviazione.

    Screenshot delle selezioni per la configurazione di un account di archiviazione per l'accesso a una rete privata.

Il file Bicep seguente illustra come configurare l'ambiente per l'esecuzione di uno script di distribuzione:

@maxLength(10) // Required maximum length, because the storage account has a maximum of 26 characters
param prefix string
param location string = resourceGroup().location
param userAssignedIdentityName string = '${prefix}Identity'
param storageAccountName string = '${prefix}stg${uniqueString(resourceGroup().id)}'
param vnetName string = '${prefix}Vnet'
param subnetName string = '${prefix}Subnet'

resource vnet 'Microsoft.Network/virtualNetworks@2025-01-01' = {
  name: vnetName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        '10.0.0.0/16'
      ]
    }
    enableDdosProtection: false
    subnets: [
      {
        name: subnetName
        properties: {
          addressPrefix: '10.0.0.0/24'
          serviceEndpoints: [
            {
              service: 'Microsoft.Storage'
            }
          ]
          delegations: [
            {
              name: 'Microsoft.ContainerInstance.containerGroups'
              properties: {
                serviceName: 'Microsoft.ContainerInstance/containerGroups'
              }
            }
          ]
        }
      }
    ]
  }
}

resource subnet 'Microsoft.Network/virtualNetworks/subnets@2024-05-01' existing = {
  parent: vnet
  name: subnetName
}
resource storageAccount 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    networkAcls: {
      bypass: 'AzureServices'
      virtualNetworkRules: [
        {
          id: subnet.id
          action: 'Allow'
          state: 'Succeeded'
        }
      ]
      defaultAction: 'Deny'
    }
  }
}

resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2025-01-31-preview' = {
  name: userAssignedIdentityName
  location: location
}

resource storageFileDataPrivilegedContributor 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = {
  name: '69566ab7-960f-475b-8e7c-b3118f30c6bd' // Storage File Data Privileged Contributor
  scope: tenant()
}

resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  scope: storageAccount

  name: guid(storageFileDataPrivilegedContributor.id, userAssignedIdentity.id, storageAccount.id)
  properties: {
    principalId: userAssignedIdentity.properties.principalId
    roleDefinitionId: storageFileDataPrivilegedContributor.id
    principalType: 'ServicePrincipal'
  }
}

È possibile usare il file Bicep seguente per testare la distribuzione:

param prefix string

param location string  = resourceGroup().location
param utcValue string = utcNow()

param storageAccountName string
param vnetName string
param subnetName string
param userAssignedIdentityName string

resource vnet 'Microsoft.Network/virtualNetworks@2025-01-01' existing = {
  name: vnetName

  resource subnet 'subnets' existing = {
    name: subnetName
  }
}

resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2025-01-31-preview' existing = {
  name: userAssignedIdentityName
}

resource dsTest 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
  name: '${prefix}DS'
  location: location
  identity: {
    type: 'userAssigned'
    userAssignedIdentities: {
      '${userAssignedIdentity.id}': {}
    }
  }
  kind: 'AzureCLI'
  properties: {
    forceUpdateTag: utcValue
    azCliVersion: '2.52.0'
    storageAccountSettings: {
      storageAccountName: storageAccountName
    }
    containerSettings: {
      subnetIds: [
        {
          id: vnet::subnet.id
        }
      ]
    }
    scriptContent: 'echo "Hello world!"'
    retentionInterval: 'P1D'
    cleanupPreference: 'OnExpiration'
  }
}

Passaggi successivi

In questo articolo si è appreso come accedere a una rete virtuale privata. Per altre informazioni, vedere: