Perché il deployment a mano non regge
Creare un logical server, un database, le firewall rule, il private endpoint e la policy di backup a lungo termine cliccando nel portale funziona una volta. Il problema arriva alla seconda: l’ambiente di test non è mai identico a quello di produzione, nessuno ricorda quale opzione era stata cambiata e la ricostruzione dopo un incidente diventa un esercizio di memoria. L’esame ragiona su questo asse: quante volte deve essere ripetuta l’operazione e quanto deve essere identico il risultato. Se la risposta è “molte volte” o “identico”, si va sul dichiarativo. Se è “una volta sola” o “dipende da cosa trovo”, l’imperativo è più diretto.
ARM e Bicep: lo stato desiderato
Un template ARM è un documento JSON che descrive lo stato desiderato delle risorse, non i passi per ottenerlo. È idempotente: applicarlo due volte non crea due server, riporta l’ambiente alla descrizione. È versionabile in un repository, quindi la configurazione di un Azure SQL Database diventa codice sottoposto a review come il resto. Bicep è un linguaggio più leggibile che viene transpilato in ARM: stesse capacità, molto meno rumore sintattico, e supporto nativo a moduli riusabili al posto dei linked template.
Due concetti pesano all’esame. Il primo sono i parameters: lo stesso template, con file di parametri diversi, produce dev, test e produzione senza duplicare codice. Il secondo sono le deployment mode: in modalità incremental il template aggiunge e aggiorna ma non tocca ciò che non è descritto; in modalità complete le risorse del resource group assenti dal template vengono eliminate. La seconda è potente per garantire allineamento ed è pericolosa se il resource group ospita anche altro.
Azure PowerShell e Azure CLI: l’approccio imperativo
Azure PowerShell (moduli Az) e Azure CLI (az) descrivono le azioni, non lo stato. Sono la scelta giusta per il lavoro operativo una tantum, per gli script che devono decidere in base a cosa trovano (leggere un valore, iterare su un elenco di database, applicare una modifica solo a chi soddisfa una condizione) e per gli step di una pipeline che orchestrano anche cose non-ARM. La scelta fra i due è quasi sempre di ecosistema e di competenze del team: PowerShell si integra naturalmente con script Windows e con l’output a oggetti, la CLI è più portabile e comoda in ambienti Linux e container. Entrambi possono comunque lanciare un deployment ARM o Bicep: dichiarativo e imperativo non si escludono, il template definisce l’infrastruttura e il comando la applica dentro la pipeline.
Lo stesso criterio vale nelle migration: l’ambiente di destinazione (Managed Instance, subnet, private endpoint, failover group) conviene descriverlo in template perché va ricostruito uguale in prova e in cutover, mentre lo spostamento dei dati resta compito di Azure Database Migration Service, del Managed Instance link, della replica transazionale o di backup e restore.
Monitorare e diagnosticare i deployment
Ogni deployment lascia traccia nella sezione Deployments del resource group, con l’elenco delle singole deployment operation, il codice e il messaggio d’errore della risorsa che ha fallito; l’Activity log e Azure Monitor completano il quadro a livello di subscription. Le cause ricorrenti sono poche e sempre le stesse: nomi già in uso (il nome del logical server è un nome DNS globalmente univoco), quote di subscription o di regione insufficienti per il service tier richiesto, dipendenze fra risorse non espresse o mal ordinate, parametri incoerenti con la piattaforma scelta. Prima di applicare conviene sempre validare: la validazione intercetta schema e riferimenti errati, mentre l’operazione what-if mostra in anticipo quali risorse verrebbero create, modificate o eliminate — l’unica difesa seria contro un deployment in modalità complete lanciato sul resource group sbagliato.
Trappole tipiche d’esame
- Ambienti dev/test/prod devono essere identici e ricostruibili → template ARM o Bicep con file di parametri: uno script PowerShell “che fa la stessa cosa” non è idempotente e non documenta lo stato finale.
- Operazione una tantum o logica condizionale su molti database → Azure CLI o Azure PowerShell: il dichiarativo descrive lo stato, non “controlla e poi decidi”; forzarlo nel template è la risposta sbagliata.
- “Le risorse non più previste devono sparire” → deployment mode complete: la incremental (default) aggiunge e aggiorna ma non rimuove nulla; attenzione all’effetto sulle risorse estranee nello stesso resource group.
- “Voglio sapere l’impatto prima di applicare” → what-if, non un deployment di prova: la sola validazione controlla sintassi e riferimenti, non l’elenco delle modifiche effettive.
- Deployment fallito per nome già in uso o quota regionale → non è un errore di template: si cambia nome parametrizzandolo, oppure si richiede l’aumento di quota o si sposta regione/service tier; rilanciare identico fallirà di nuovo.
- Migrazione verso Managed Instance da ripetere in prova e in cutover → target da template, dati con Azure Database Migration Service o Managed Instance link: provisioning e movimentazione dati sono due problemi distinti, con strumenti distinti.