Condividi tramite


Moduli Bicep

Con Bicep è possibile organizzare le distribuzioni in moduli. Un modulo è un file Bicep distribuito da un altro file Bicep. Un modulo può anche essere un modello di Azure Resource Manager per JSON. Con i moduli è possibile migliorare la leggibilità dei file Bicep incapsulando dettagli complessi della distribuzione. È anche possibile riutilizzare facilmente i moduli per distribuzioni diverse.

Per condividere moduli con altri utenti dell'organizzazione, creare una specifica di modello o un registro privato. Le specifiche di modello e i moduli nel Registro di sistema sono disponibili solo per gli utenti con le autorizzazioni corrette.

Suggerimento

La scelta tra il modulo del registro di sistema e le specifiche di modello è principalmente una questione di preferenza. Quando si sceglie tra i due, è necessario considerare alcuni aspetti:

  • Il registro dei moduli è supportato solo da Bicep. Se ancora non si usa Bicep, usare le specifiche del modello.
  • È possibile distribuire il contenuto nel Registro di sistema dei moduli Bicep solo da un altro file Bicep. È possibile distribuire le specifiche dei modelli direttamente dall'API, Da Azure PowerShell, dall'interfaccia della riga di comando di Azure e dal portale di Azure. È anche possibile usare UiFormDefinition per personalizzare l'esperienza di distribuzione del portale.
  • Bicep permette alcune funzionalità limitate per l'incorporamento di altri artefatti del progetto (inclusi file non-Bicep e non-ARM-template come script di PowerShell, script CLI (interfaccia della riga di comando) e altri file binari) usando le funzioni loadTextContent e loadFileAsBase64. Le specifiche di modello non possono creare pacchetti di questi artefatti.

I moduli Bicep vengono convertiti in un singolo modello di Resource Manager con modelli annidati. Per altre informazioni su come Bicep risolve i file di configurazione e su come Bicep unisce un file di configurazione definito dall'utente con il file di configurazione predefinito, vedere Processo di risoluzione dei file di configurazione e Processo di unione file di configurazione.

Risorse di formazione

Per informazioni sui moduli tramite istruzioni dettagliate, vedere Creare file Bicep componibili usando i moduli.

Definire i moduli

La sintassi di base per la definizione di un modulo è:

@<decorator>(<argument>)
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

Un semplice esempio reale è simile al seguente:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

È possibile utilizzare un template ARM per JSON come modulo:

module stgModule '../storageAccount.json' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Usare il nome simbolico per fare riferimento al modulo in un'altra parte del file Bicep. Ad esempio, è possibile usare il nome simbolico per ottenere l'output da un modulo. Il nome simbolico può contenere a-z, A-Z, 0-9 e il carattere di sottolineatura (_). Il nome non può iniziare con un numero. Un modulo non può avere lo stesso nome di un parametro, una variabile o una risorsa.

Il percorso può essere un file locale o un file in un registro di sistema. Il file locale può essere un file Bicep o un modello ARM JSON. Per altre informazioni, vedere Percorso di un modulo.

La proprietà name è facoltativa. Diventa il nome della risorsa di distribuzione nidificata nel modello generato. Se non viene specificato alcun nome, verrà generato un GUID come nome della risorsa di distribuzione nidificata.

Se un modulo con un nome statico viene distribuito contemporaneamente allo stesso ambito, è possibile che una distribuzione interferisca con l'output dell'altra distribuzione. Ad esempio, se due file Bicep usano lo stesso modulo con lo stesso nome statico (examplemodule) e sono destinati allo stesso gruppo di risorse, una distribuzione potrebbe mostrare l'output errato. Se si è interessati alle distribuzioni simultanee nello stesso ambito, assegnare al modulo un nome univoco. Un altro modo per garantire nomi univoci per i moduli è omettere la proprietà name, in questo modo verrà generato automaticamente un nome di modulo univoco.

Nell'esempio seguente il nome della distribuzione viene concatenato al nome del modulo. Se si specifica un nome univoco per la distribuzione, anche il nome del modulo è univoco.

module stgModule 'storageAccount.bicep' = {
  name: '${deployment().name}-storageDeploy'
  scope: resourceGroup('demoRG')
}

Non specificare alcun nome di modulo è valido. Un GUID verrà generato come nome del modulo.

module stgModule 'storageAccount.bicep' = {
  scope: resourceGroup('demoRG')
}

Se è necessario specificare un ambito diverso dall'ambito per il file principale, aggiungere la proprietà scope. Per altre informazioni, vedere Impostare l'ambito del modulo.

// deploy to different scope
module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  scope: <scope-object>
  params: {
    <parameter-names-and-values>
  }
}

Per distribuire un modulo in modo condizionale, aggiungere un'espressione if. È simile alla distribuzione condizionale di una risorsa.

// conditional deployment
module <symbolic-name> '<path-to-file>' = if (<condition-to-deploy>) {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}

Per distribuire più istanze di un modulo, aggiungere l'espressione for. Usare il decoratore batchSize per specificare se le istanze vengono distribuite serialmente o in parallelo. Per altre informazioni, vedere Cicli iterativi in Bicep.

// iterative deployment
@batchSize(int) // optional decorator for serial deployment
module <symbolic-name> '<path-to-file>' = [for <item> in <collection>: {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
}]

Analogamente alle risorse, i moduli vengono distribuiti in parallelo, a meno che non dipendano da altri moduli o risorse. In genere, non è necessario impostare le dipendenze perché vengono determinate in modo implicito. Se è necessario impostare una dipendenza esplicita, aggiungere dependsOn alla definizione del modulo. Per altre informazioni sulle dipendenze, vedere Dipendenze delle risorse in Bicep.

module <symbolic-name> '<path-to-file>' = {
  name: '<linked-deployment-name>'
  params: {
    <parameter-names-and-values>
  }
  dependsOn: [
    <symbolic-names-to-deploy-before-this-item>
  ]
}

Percorso di un modulo

Il file per il modulo può essere un file locale o un file esterno. Il file esterno può trovarsi di una specifica do modello o in un registro di moduli Bicep.

File locale

Se il modulo è un file locale, specificare un percorso relativo a tale file. Tutti i percorsi in Bicep devono essere specificati usando il separatore di directory barra (/) per garantire una compilazione coerente tra le piattaforme. Il carattere barra rovesciata di Windows (\) non è supportato. I percorsi possono contenere spazi.

Ad esempio, per distribuire un file con un livello superiore nella directory dal file principale, usare:

module stgModule '../storageAccount.bicep' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

File nel registro di sistema

Sono disponibili registri di moduli pubblici e privati.

Registro dei moduli pubblici

Nota

I moduli non verificati di Azure vengono ritirati dal registro dei moduli pubblici.

I moduli verificati di Azure sono moduli predefiniti, pretestati e preverificati che è possibile usare per distribuire le risorse in Azure. I dipendenti Microsoft hanno creato e sono proprietari di questi moduli. Sono stati progettati per semplificare e accelerare il processo di distribuzione per le risorse e le configurazioni comuni di Azure. I moduli sono allineati anche alle procedure consigliate, ad esempio Azure Well-Architected Framework.

Esplorare i moduli Bicep per visualizzare l'elenco dei moduli disponibili. Selezionare i numeri evidenziati nello screenshot seguente per passare direttamente alla visualizzazione filtrata:

Screenshot che mostra i moduli verificati di Azure.

L'elenco dei moduli mostra la versione più recente. Selezionare il numero di versione per visualizzare un elenco delle versioni disponibili.

Screenshot che mostra le versioni dei moduli verificati di Azure.

Per collegarsi a un modulo pubblico, specificare il percorso del modulo con la sintassi seguente:

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public: alias per i moduli pubblici. È possibile personalizzare questo alias nel file di configurazione Bicep.
  • percorso file: può contenere segmenti che è possibile separare con il / carattere .
  • tag: viene usato per specificare una versione per il modulo.

Ad esempio:

module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

Nota

L'alias per i moduli pubblici è br/public. È anche possibile scriverlo come segue:

module <symbolic-name> 'br:mcr.microsoft.com/bicep/<file-path>:<tag>' = {}

Registro dei moduli privati

Se è stato pubblicato un modulo in un registro, è possibile collegarsi a tale modulo. Specificare il nome del registro Azure Container e un percorso del modulo. Specificare il percorso del modulo con la sintassi seguente:

module <symbolic-name> 'br:<registry-name>.azurecr.io/<file-path>:<tag>' = {
  • br: il nome dello schema per un registro di sistema Bicep.
  • percorso del file: viene chiamato repository in Registro Azure Container. Il percorso del file può contenere segmenti separati dal / carattere .
  • tag: viene usato per specificare una versione per il modulo.

Ad esempio:

module stgModule 'br:exampleregistry.azurecr.io/bicep/modules/storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Quando si fa riferimento a un modulo in un registro, l'estensione Bicep in Visual Studio Code chiama bicep restore automaticamente per copiare il modulo esterno nella cache locale. Il ripristino del modulo esterno richiede alcuni istanti. Se IntelliSense per il modulo non funziona immediatamente, attendere il completamento del ripristino.

Il percorso completo di un modulo in un registro può essere lungo. Anziché specificare il percorso completo ogni volta che si vuole usare il modulo, configurare gli alias nel file bicepconfig.json. Gli alias semplificano il riferimento al modulo. Ad esempio, con un alias, è possibile abbreviare il percorso in:

module stgModule 'br/ContosoModules:storage:v1' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Il registro dei moduli pubblici ha un alias predefinito:

module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

È possibile eseguire l'override dell'alias pubblico nel file bicepconfig.json .

File nella specifica del modello

Dopo aver creato una specifica di modello, collegarla a tale specifica di modello in un modulo. Specificare la specifica di modello nel formato seguente:

module <symbolic-name> 'ts:<sub-id>/<rg-name>/<template-spec-name>:<version>' = {

Per semplificare il file Bicep, creare un alias per il gruppo di risorse che contiene le specifiche del modello. Quando si usa un alias, la sintassi diventa:

module <symbolic-name> 'ts/<alias>:<template-spec-name>:<version>' = {

Il modulo seguente distribuisce una specifica di modello per creare un account di archiviazione. La sottoscrizione e il gruppo di risorse per la specifica di modello sono definiti nell'alias denominato ContosoSpecs.

module stgModule 'ts/ContosoSpecs:storageSpec:2.0' = {
  name: 'storageDeploy'
  params: {
    storagePrefix: 'examplestg1'
  }
}

Usare elementi Decorator

Gli elementi Decorator vengono scritti nel formato @expression e vengono posizionati sopra le dichiarazioni di modulo. La tabella seguente mostra i decorator disponibili per i moduli:

Decoratore Argomento Descrizione
batchSize Nessuno Consente di configurare le istanze da distribuire in sequenza.
descrizione stringa Specificare le descrizioni per il modulo.

I Decorator si trovano nello spazio dei nomi sys. Se devi distinguere un decorator da un altro oggetto con lo stesso nome, anteponi al decorator il prefisso sys. Ad esempio, se il file Bicep include un parametro denominato description, è necessario aggiungere lo spazio dei nomi sys quando si usa il decoratore description.

BatchSize

È possibile applicare @batchSize() solo a una definizione di risorsa o di modulo che usa un'espressionefor.

Per impostazione predefinita, i moduli vengono distribuiti in parallelo. Quando si aggiunge il decoratore @batchSize(int), si distribuiscono le istanze in modo seriale.

@batchSize(3)
module storage 'br/public:avm/res/storage/storage-account:0.11.1' = [for storageName in storageAccounts: {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}]

Per altre informazioni, vedere Distribuire in batch.

Descrizione

Per aggiungere una spiegazione, aggiungere una descrizione alle dichiarazioni di modulo. Ad esempio:

@description('Create storage accounts referencing an AVM.')
module storage 'br/public:avm/res/storage/storage-account:0.18.0' = {
  name: 'myStorage'
  params: {
    name: 'store${resourceGroup().name}'
  }
}

È possibile usare il testo in formato Markdown per il testo della descrizione.

Parametri

I parametri specificati nella definizione del modulo corrispondono ai parametri nel file Bicep.

L'esempio Bicep seguente ha tre parametri: storagePrefix, storageSKUe location. Il storageSKU parametro ha un valore predefinito, pertanto non è necessario specificare un valore per tale parametro durante la distribuzione.

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

Per usare l'esempio precedente come modulo, specificare i valori per tali parametri.

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

Impostare l'ambito del modulo

Quando si dichiara un modulo, impostare un ambito per il modulo diverso dall'ambito del file Bicep che lo contiene. Utilizzare la proprietà scope per impostare l'ambito del modulo. Quando la proprietà scope non viene specificata, il modulo viene distribuito nell'ambito di destinazione dell'elemento padre.

Il file Bicep seguente crea un gruppo di risorse e un account di archiviazione in tale gruppo di risorse. Il file viene distribuito in una sottoscrizione, ma il modulo ha come ambito il nuovo gruppo di risorse.

// set the target scope for this file
targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

param location string = deployment().location

var resourceGroupName = '${namePrefix}rg'

resource newRG 'Microsoft.Resources/resourceGroups@2024-03-01' = {
  name: resourceGroupName
  location: location
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: newRG
  params: {
    storagePrefix: namePrefix
    location: location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

Nell'esempio seguente vengono distribuiti gli account di archiviazione in due gruppi di risorse diversi. Entrambi questi gruppi di risorse devono già esistere.

targetScope = 'subscription'

resource firstRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
  name: 'demogroup2'
}

module storage1 '../create-storage-account/main.bicep' = {
  name: 'westusdeploy'
  scope: firstRG
  params: {
    storagePrefix: 'stg1'
    location: 'westus'
  }
}

module storage2 '../create-storage-account/main.bicep' = {
  name: 'eastusdeploy'
  scope: secondRG
  params: {
    storagePrefix: 'stg2'
    location: 'eastus'
  }
}

Impostare la scope proprietà su un oggetto ambito valido. Se il file Bicep distribuisce un gruppo di risorse, una sottoscrizione o un gruppo di gestione, è possibile impostare l'ambito di un modulo sul nome simbolico per tale risorsa. In alternativa, è possibile usare le funzioni di ambito per ottenere un ambito valido.

Queste funzioni sono:

Nell'esempio seguente viene utilizzata la managementGroup funzione per impostare l'ambito.

param managementGroupName string

module mgDeploy 'main.bicep' = {
  name: 'deployToMG'
  scope: managementGroup(managementGroupName)
}

Risultato

È possibile ottenere valori da un modulo e usarli nel file Bicep principale. Per ottenere un valore di output da un modulo, usare la proprietà outputs nell'oggetto modulo.

Il primo esempio crea un account di archiviazione e restituisce gli endpoint primari:

@minLength(3)
@maxLength(11)
param storagePrefix string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GZRS'
  'Standard_RAGZRS'
])
param storageSKU string = 'Standard_LRS'

param location string

var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'

resource stg 'Microsoft.Storage/storageAccounts@2023-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

Quando la proprietà viene usata come modulo, è possibile ottenere tale valore di output:

targetScope = 'subscription'

@minLength(3)
@maxLength(11)
param namePrefix string

resource demoRG 'Microsoft.Resources/resourceGroups@2024-03-01' existing = {
  name: 'demogroup1'
}

module stgModule '../create-storage-account/main.bicep' = {
  name: 'storageDeploy'
  scope: demoRG
  params: {
    storagePrefix: namePrefix
    location: demoRG.location
  }
}

output storageEndpoint object = stgModule.outputs.storageEndpoint

Con Bicep versione 0.35.1 e successive, l'elemento @secure() Decorator può essere applicato agli output del modulo per contrassegnarli come sensibili, assicurandosi che i relativi valori non siano esposti nei log o nella cronologia di distribuzione. Ciò è utile quando un modulo deve restituire dati sensibili, ad esempio una chiave generata o una stringa di connessione, al file Bicep padre senza rischiare l'esposizione. Per altre informazioni, vedere Proteggere gli output.