Raggruppare le risorse correlate per mezzo di moduli

Completato

Si è iniziato ad adottare modelli Bicep per alcuni recenti lanci di prodotti e questa iniziativa ha avuto successo. Poiché le risorse sono state dichiarate in un file modello, è possibile ora distribuire rapidamente le risorse necessarie per nuovi lanci di giocattoli senza doverle configurare manualmente nel portale di Azure.

Il responsabile IT si accorge che il codice Bicep sta diventando sempre più complesso, anche a causa di un numero crescente di risorse definite, e chiede quindi se sia possibile renderlo più modularizzato. È possibile creare singoli file Bicep, chiamati moduli, per diverse parti della distribuzione, a cui può fare riferimento il modello Bicep principale. Dietro le quinte, i moduli vengono convertiti tramite transpile in un singolo modello JSON per la distribuzione.

I moduli consentono anche di rendere il codice Bicep ancora più facilmente riutilizzabile. È infatti possibile che un singolo modulo Bicep venga usato da molti altri modelli Bicep.

Inoltre, sarà spesso necessario emettere output dai moduli e dai modelli Bicep. Gli output consentono al codice Bicep di restituire dati alla persona o allo strumento che ha avviato la distribuzione. Si esamineranno per primi gli output.

Nota

I comandi riportati in questa unità vengono illustrati per spiegare i concetti. Non eseguire ancora i comandi. Presto sarà possibile provare quanto appreso.

Output

Un utente può distribuire manualmente modelli Bicep o un processo di rilascio automatizzato può distribuirli. In entrambi i casi, è piuttosto comune che dal modello vengano generati dati che devono essere inviati alla persona o allo strumento che sta effettuando la distribuzione del modello.

Di seguito sono riportati alcuni scenari di esempio in cui potrebbe essere necessario ottenere informazioni dalla distribuzione del modello:

  • Si crea un modello Bicep che distribuisce una macchina virtuale ed è necessario ottenere l'indirizzo IP pubblico per poter usare SSH nel computer.
  • Si crea un modello Bicep che accetta un set di parametri, quali un nome di ambiente e un nome di applicazione. Il modello usa un'espressione per assegnare un nome a un'app del Servizio app di Azure distribuita. È necessario eseguire l'output del nome dell'app distribuita dal modello in modo che possa essere usato in una pipeline di distribuzione per pubblicare i file binari dell'applicazione.

Gli output possono essere quindi usati per questi scenari. Per definire un output in un modello Bicep, usare la parola chiave output, come illustrato di seguito:

output appServiceAppName string = appServiceAppName

La definizione di output include alcune parti chiave:

  • La parola chiave output indica a Bicep che si sta definendo un output.
  • appServiceAppName è il nome dell'output. Se un utente distribuisce correttamente il modello, i valori di output contengono il nome specificato, in modo che l'utente possa accedere facilmente ai valori desiderati.
  • string è il tipo di output. Gli output del linguaggio Bicep supportano gli stessi tipi dei parametri.
  • Per ogni output è necessario specificare un valore. A differenza dei parametri, infatti, agli output deve essere sempre associato un valore. I valori di output possono essere espressioni, riferimenti a parametri o variabili o proprietà delle risorse distribuite nel file.

Suggerimento

Gli output possono usare gli stessi nomi delle variabili e dei parametri. Questa convenzione può essere utile se si costruisce un'espressione complessa all'interno di una variabile da usare nelle risorse del modello ed è anche necessario esporre il valore della variabile come output.

Di seguito è riportato un altro esempio di output. In questo caso il valore sarà impostato sul nome di dominio completo della risorsa di un indirizzo IP pubblico.

output ipFqdn string = publicIPAddress.properties.dnsSettings.fqdn

Suggerimento

Cercare di usare proprietà di risorse come output, anziché azzardare supposizioni sul comportamento delle risorse. Ad esempio, se è necessario che venga generato un output per l'URL di un'app del Servizio app di Azure, usare la proprietà defaultHostName dell'app anziché creare autonomamente una stringa per l'URL. Talvolta, infatti, queste supposizioni non sono valide in ambienti diversi oppure è possibile che cambi il comportamento di una risorsa ed è quindi più sicuro che le proprietà della risorsa siano indicate al suo interno.

Attenzione

Non creare output per valori di segreti quali stringhe o chiavi di connessione. Chiunque abbia accesso al gruppo di risorse, infatti, può leggere gli output generati dai modelli. Per accedere alle proprietà di risorse dei segreti è possibile adottare altri approcci che verranno trattati in un modulo successivo.

Definire un modulo

I moduli Bicep consentono di organizzare e riusare il codice Bicep creando unità più piccole che possono essere composte in un modello. Qualsiasi modello Bicep, inoltre, può essere usato come modulo da un altro modello. In questo modulo di apprendimento sono stati creati modelli Bicep. ovvero file che potranno essere usati come moduli Bicep.

Si supponga di avere un modello Bicep che distribuisce le risorse di applicazione, database e rete per la soluzione A. È possibile suddividere questo modello in tre moduli, ciascuno incentrato su uno specifico set di risorse. Come ulteriore vantaggio, è ora possibile riusare i moduli anche in altri modelli per altre soluzioni. Quando si sviluppa un modello per la soluzione B, che presenta requisiti di rete simili alla soluzione A, è possibile riusare il modulo di rete.

Diagramma che mostra un modello per la soluzione A che fa riferimento a tre moduli: applicazione, database e rete. Il modulo di rete viene quindi riusato in un altro modello per la soluzione B.

Quando si vuole che il modello includa un riferimento a un file del modulo, usare la parola chiave module. Una definizione di modulo è simile a una dichiarazione di risorsa ma, anziché includere un tipo di risorsa e una versione dell'API, si userà il nome file del modulo:

module myModule 'modules/mymodule.bicep' = {
  name: 'MyModule'
  params: {
    location: location
  }
}

Nell'elenco seguente vengono esaminati gli elementi chiave di questa definizione di modello:

  • La parola chiave module indica a Bicep che si sta per usare un altro file Bicep come modulo.
  • Proprio come le risorse, i moduli richiedono un nome simbolico come myModule. che viene usato quando si fa riferimento agli output del modulo in altre parti del modello.
  • modules/mymodule.bicep è il percorso del file del modulo, relativo al file del modello. Tenere presente che un file di modulo è solo un normale file Bicep.
  • Come per le risorse, la proprietà name è obbligatoria. Azure usa il nome del modulo poiché crea una distribuzione separata per ogni modulo all'interno del file del modello. Ogni distribuzione presenta quindi un nome che consente di identificarla con facilità.
  • È possibile specificare qualsiasi parametro del modulo usando la parola chiave params. Quando si impostano i valori dei parametri contenuti nel modello, è possibile usare espressioni, parametri di modello, variabili, proprietà delle risorse distribuite all'interno del modello e output di altri moduli. Bicep comprenderà automaticamente le dipendenze tra le risorse.

Moduli e output

Come i modelli, anche i moduli Bicep possono definire output. È prassi comune concatenare più moduli all'interno di un modello. In questo caso, l'output di un modulo può diventare un parametro per un altro modulo. Combinando moduli e output, è quindi possibile creare file Bicep efficaci e riutilizzabili.

Progettare un modulo

Per costruire un modulo Bicep ben strutturato, è importante rispettare alcuni principi chiave:

  • Un modulo deve avere uno scopo preciso. È possibile usare un modulo per definire tutte le risorse correlate a una parte specifica della soluzione. Ad esempio, è possibile creare un modulo contenente tutte le risorse usate per monitorare l'applicazione. È anche possibile usare un modulo per definire un set di risorse correlate tra loro, come tutti i database e i server di database.

  • Non inserire ogni risorsa in un modulo separato. Non è consigliabile creare un modulo separato per ogni risorsa distribuita. In presenza di una risorsa con molte proprietà complesse, potrebbe essere utile inserirla in un modulo separato. In generale, tuttavia, è preferibile che nei moduli vengano combinate più risorse.

  • Un modulo deve avere parametri e output chiari e sensati. Tenere sempre presente lo scopo del modulo. Cercare di capire se il modulo dovrebbe poter modificare i valori dei parametri o se questa operazione dovrebbe essere gestita dal modello padre, che dovrebbe poi passare un singolo valore al modulo. Analogamente, cercare di intuire gli output che dovrebbero essere restituiti da un modulo e assicurarsi che siano utili per i modelli che useranno il modulo.

  • Un modulo deve essere il più indipendente possibile. Se un modulo deve usare una variabile per definire una parte di un modulo, in genere la variabile deve essere inclusa nel file del modulo anziché nel modello padre.

  • Un modulo non deve eseguire l'output di segreti. Come per i modelli, è importante che un modulo non generi output relativi a valori di segreti, quali stringhe o chiavi di connessione.