Moduli Bicep

Bicep consente di organizzare le distribuzioni in moduli. Un modulo è un file Bicep (o un modello JSON ARM) distribuito da un altro file Bicep. 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, un registro pubblico 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 Registro di sistema dei moduli e le specifiche di modello è principalmente una questione di preferenza. Quando si sceglie tra i due elementi, è necessario considerare alcuni aspetti:

  • Il Registro di sistema dei moduli è supportato solo da Bicep. Se non si usa ancora Bicep, usare le specifiche del modello.
  • Il contenuto nel Registro di sistema del modulo Bicep può essere distribuito solo da un altro file Bicep. Le specifiche dei modelli possono essere distribuite direttamente dall'API, Da Azure PowerShell, dall'interfaccia della riga di comando di Azure e dalla portale di Azure. È anche possibile usare UiFormDefinition per personalizzare l'esperienza di distribuzione del portale.
  • Bicep include alcune funzionalità limitate per l'incorporamento di altri artefatti del progetto (inclusi i file non Bicep e non arm-template. Ad esempio, script di PowerShell, script dell'interfaccia della riga di comando e altri file binari) usando le loadTextContent funzioni e loadFileAsBase64 . Le specifiche di modello non possono creare pacchetti di questi artefatti.

I moduli Bicep vengono convertiti in un singolo modello di Azure Resource Manager con modelli annidati. Per altre informazioni su come Bicep risolve i file di configurazione e sul modo in cui Bicep unisce il 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

Se si preferisce ottenere informazioni sui moduli tramite istruzioni dettagliate, vedere Creare file Bicep componibili usando i moduli.

Sintassi della definizione

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

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

Di conseguenza, un semplice esempio reale sarà simile al seguente:

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

È anche possibile usare un modello JSON arm 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, di una variabile o di 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 JSON arm. Per altre informazioni, vedere Percorso del modulo.

La proprietà name è obbligatoria. Diventa il nome della risorsa di distribuzione nidificata nel modello generato.

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 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.

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')
}

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 in modo condizionale un modulo, aggiungere un'espressione if . L'uso è 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 . È possibile usare l'elemento batchSize Decorator per specificare se le istanze vengono distribuite in modo seriale 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 dipendono da altri moduli o risorse. In genere, non è necessario impostare le dipendenze perché vengono determinate in modo implicito. Se è necessario impostare una dipendenza esplicita, è possibile aggiungere dependsOn alla definizione del modulo. Per altre informazioni sulle dipendenze, vedere Dipendenze delle risorse.

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

Percorso del modulo

Il file per il modulo può essere un file locale o un file esterno. Il file esterno può trovarsi nella specifica del modello o in un registro di moduli Bicep. Tutte queste opzioni sono illustrate di seguito.

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

Registro dei moduli pubblici

Il registro dei moduli pubblici è ospitato in un registro contenitori Microsoft . Il codice sorgente e i moduli vengono archiviati in GitHub. Per visualizzare i moduli disponibili e le relative versioni, vedere Indice del modulo del Registro di sistema Bicep.

The screenshot of public module registry.

Selezionare le versioni per visualizzare le versioni disponibili. È anche possibile selezionare Codice sorgente per visualizzare il codice sorgente del modulo e aprire i file Leggimi.

Attualmente sono disponibili solo alcuni moduli pubblicati. Verranno visualizzati altri moduli. Per contribuire al Registro di sistema, vedere la guida ai contributi.

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

module <symbolic-name> 'br/public:<file-path>:<tag>' = {}
  • br/public è l'alias del Registro di sistema del modulo pubblico. Questo alias è predefinito nella configurazione.
  • il percorso del file può contenere segmenti che possono essere separati dal / carattere .
  • tag viene usato per specificare una versione per il modulo.

Ad esempio:

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

Nota

br/public è l'alias del registro pubblico. Può anche essere scritto come

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 Bicep.
  • il 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 automaticamente il ripristino bicep 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, è possibile 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'
  }
}

È stato predefinito un alias per il Registro di sistema del modulo pubblico:

module hw 'br/public:samples/hello-world:1.0.2' = {
  name: 'helloWorld'
  params: {
    name: 'John Dole'
  }
}

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

File nella specifica del modello

Dopo aver creato una specifica di modello, è possibile collegarsi 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>' = {

Tuttavia, è possibile semplificare il file Bicep creando 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'
  }
}

Parametri

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

L'esempio Bicep seguente include tre parametri: storagePrefix, storageSKU e location. Il parametro storageSKU 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@2021-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@2021-04-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, è possibile impostare un ambito per il modulo diverso dall'ambito per il file Bicep contenitore. Usare la scope proprietà per impostare l'ambito per il 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@2021-04-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@2021-04-01' existing = {
  name: 'demogroup1'
}

resource secondRG 'Microsoft.Resources/resourceGroups@2021-04-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 proprietà scope 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)
}

Output

È possibile ottenere valori da un modulo e usarli nel file Bicep principale. Per ottenere un valore di output da un modulo, usare la proprietà nell'oggetto outputs 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@2021-04-01' = {
  name: uniqueStorageName
  location: location
  sku: {
    name: storageSKU
  }
  kind: 'StorageV2'
  properties: {
    supportsHttpsTrafficOnly: true
  }
}

output storageEndpoint object = stg.properties.primaryEndpoints

Se usato come modulo, è possibile ottenere tale valore di output.

targetScope = 'subscription'

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

resource demoRG 'Microsoft.Resources/resourceGroups@2021-04-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

Passaggi successivi