Torna al catalogo
Season 26 10 Episodi 39 min 2026

Azure Pipelines

Edizione 2026. Prendi confidenza con Azure DevOps (ADO) e scopri come creare pipeline ben strutturate. Impara le best practice, gestisci variabili e segreti e ottieni consigli pratici su come utilizzarlo per le esigenze di sviluppo software enterprise.

CI/CD DevOps
Azure Pipelines
In Riproduzione
Click play to start
0:00
0:00
1
YAML vs Classic Pipelines
Introduciamo le Azure DevOps Pipelines ed esploriamo il passaggio fondamentale dalle pipeline basate sulla Classic UI alla Pipeline-as-Code utilizzando YAML. Scoprirai perché archiviare le configurazioni della pipeline insieme al codice della tua applicazione è lo standard di settore per il software enterprise.
3m 26s
2
Anatomia di una Pipeline: Stages, Jobs e Steps
Immergiti nella gerarchia strutturale delle Azure Pipelines. Imparerai come organizzare logicamente il tuo processo di CI/CD utilizzando gli Stages, distribuire i carichi di lavoro con i Jobs ed eseguire comandi esatti con gli Steps.
4m 04s
3
Contesto di Esecuzione: Agents e Demands
Scopri come le Azure Pipelines eseguono il tuo codice utilizzando gli Agents. Trattiamo le differenze tra gli agent Microsoft-hosted e Self-hosted, e come utilizzare i Demands per instradare i job verso l'infrastruttura corretta.
4m 16s
4
Automatizzare il Workflow con i Triggers
Impara a far reagire automaticamente le tue pipeline agli eventi. Esploriamo i trigger di Continuous Integration (CI), i trigger di Pull Request (PR) e i trigger Scheduled per orchestrare cadenze di rilascio complesse.
3m 37s
5
Gestione dello Stato: Variables e Variable Groups
Padroneggia l'arte di passare stato e configurazione attraverso le tue pipeline. Questo episodio analizza le variabili di sistema predefinite, le variabili di pipeline personalizzate e come condividere le configurazioni tra i progetti utilizzando i Variable Groups.
3m 44s
6
Proteggere i Secrets con Azure Key Vault
Smetti di memorizzare credenziali sensibili nel tuo strumento di CI/CD. Spieghiamo come integrare Azure Key Vault nelle Azure Pipelines per recuperare dinamicamente password, chiavi API e stringhe di connessione a runtime.
4m 06s
7
Controllo Dinamico: Conditions ed Expressions
Impara a rendere le tue pipeline intelligenti e reattive. Approfondiamo le Conditions e le Expressions personalizzate per controllare dinamicamente quali job e step eseguire in base ai valori delle variabili e agli esiti dei job precedenti.
3m 37s
8
Riusabilità Enterprise: YAML Templates
Scala l'architettura della tua pipeline su decine di repository utilizzando gli YAML Templates. Impara la differenza tra 'Includes' ed 'Extends' e come applicare i requisiti di sicurezza a livello aziendale.
4m 07s
9
Indirizzare i Deployment con gli Environments
Eleva la tua pipeline dalla semplice 'esecuzione di codice' alla gestione di veri e propri deployment. Trattiamo il tipo Deployment Job, gli Environments e le strategie di deployment come runOnce e Canary.
4m 11s
10
Enterprise Gates: Approvals e Checks
Metti dei paletti ai tuoi deployment automatizzati. In questo episodio finale, esploriamo come configurare Approvals, Branch Control ed Exclusive Locks sui tuoi Environments per proteggere la produzione.
4m 15s

Episodi

1

YAML vs Classic Pipelines

3m 26s

Introduciamo le Azure DevOps Pipelines ed esploriamo il passaggio fondamentale dalle pipeline basate sulla Classic UI alla Pipeline-as-Code utilizzando YAML. Scoprirai perché archiviare le configurazioni della pipeline insieme al codice della tua applicazione è lo standard di settore per il software enterprise.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 1 di 10. Clicchi su un'interfaccia web, trascini qualche box, e la tua build funziona perfettamente. Poi qualcuno modifica un'impostazione, la build si rompe, e non hai assolutamente alcuna history di chi ha fatto cosa o perché. Questa è la trappola dei visual editor, ed è esattamente il motivo per cui il passaggio dalla Classic UI alle pipeline YAML è alla base della moderna CI/CD. Azure Pipelines ti offre due modi distinti per automatizzare la tua software delivery. Il metodo più vecchio è l'interfaccia Classic. Si basa su un portale web grafico in cui configuri i task usando form e menu a tendina. Sembra accessibile quando sei agli inizi. Ma man mano che il tuo sistema cresce, l'approccio Classic diventa un grosso problema. La configurazione risiede nel database di Azure DevOps, completamente scollegata dal tuo codice sorgente effettivo. Le pipeline YAML sostituiscono tutto questo con il concetto di Pipeline-as-Code. Invece di configurare le impostazioni in un portale web, definisci l'intero processo di build e release in un semplice file di testo. Fai il commit di questo file YAML direttamente nel tuo repository, tenendolo proprio accanto al codice dell'applicazione di cui deve fare la build. Alcuni sviluppatori esitano a fare il passaggio, temendo che una configurazione basata su testo possa limitare le feature rispetto al visual editor. Non è così. Le pipeline YAML offrono una completa feature parity per la continuous integration e la continuous delivery. Microsoft considera la Classic UI legacy e concentra i nuovi sviluppi su YAML. È lo standard enterprise per la ripetibilità e l'auditing. Pensa a un team che migra una complessa build definition drag-and-drop in un file nel repository. Nel vecchio sistema, testare un nuovo build step significava modificare la configurazione condivisa della pipeline, rischiando di rompere la build per il resto del team. Con YAML, la pipeline è sotto version control, proprio come la tua applicazione. Se crei un feature branch per aggiornare una dipendenza core, puoi modificare il file YAML in quello stesso identico branch. La logica di build aggiornata si applica solo al tuo branch isolato. Il resto del team continua a utilizzare la pipeline del main branch senza interruzioni. Ecco il punto chiave. Dato che la tua pipeline ora è semplicemente un file di testo in Git, rientra nel tuo normale processo di code review. Quando abbandoni la UI, nessuno può alterare silenziosamente un deployment target o saltare un testing step. Ogni modifica alla pipeline richiede un commit. Richiede una pull request. Richiede l'approvazione di un collega. Ottieni un audit trail permanente e inconfutabile di ogni modifica. Inoltre, lo stato della tua pipeline è vincolato per sempre allo stato della tua applicazione. Se hai bisogno di fare un roll back a una release di sei mesi fa, il file YAML di quel preciso momento è conservato nella tua Git history. Hai la garanzia di avere le istruzioni di build corrette per quella specifica vecchia versione del codice. Il passaggio a YAML significa trattare il tuo delivery mechanism con lo stesso identico rigore ingegneristico del software che distribuisce. Se trovi utili questi episodi e vuoi supportare lo show, puoi cercare DevStoriesEU su Patreon. Questo è tutto per questo episodio. Grazie per l'ascolto, e continua a sviluppare!
2

Anatomia di una Pipeline: Stages, Jobs e Steps

4m 04s

Immergiti nella gerarchia strutturale delle Azure Pipelines. Imparerai come organizzare logicamente il tuo processo di CI/CD utilizzando gli Stages, distribuire i carichi di lavoro con i Jobs ed eseguire comandi esatti con gli Steps.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 2 di 10. La differenza tra uno stage e un job determina esattamente dove la tua pipeline si interromperà se non capisci l'allocazione degli agent. Se sbagli, potresti ritrovarti senza i tuoi artifact di build proprio quando è il momento di far girare i test. L'anatomia di una pipeline, in particolare stage, job e step, è la struttura che risolve questo problema. Una pipeline è un sistema gerarchico. Questa struttura impone rigorosamente come il lavoro viene suddiviso, dove viene eseguito e in quale ordine. La gerarchia è a tre livelli. Gli stage contengono i job, e i job contengono gli step. Uno stage funge da confine logico. Raggruppa il lavoro correlato. In un'applicazione enterprise, usi gli stage per separare le fasi principali del tuo ciclo di delivery del software. Potresti definire uno stage di build, seguito da uno stage di testing separato. Di default, gli stage vengono eseguiti in sequenza. Uno stage deve terminare completamente prima che inizi quello successivo. Fungono da barriere organizzative per il tuo processo generale. Ecco il punto chiave. Spesso gli ingegneri confondono stage e job, trattandoli come sinonimi. Non servono allo stesso scopo. Uno stage è un contenitore puramente logico. Un job è un confine di esecuzione fisico. Un job definisce l'ambiente effettivo in cui gira il tuo codice. Ogni job viene assegnato a un agent, ovvero la macchina o il container che esegue i tuoi task. Tutte le operazioni all'interno di un singolo job vengono eseguite su quello specifico agent. Dato che i job sono l'unità di esecuzione, si comportano in modo diverso dagli stage. Se inserisci tre job all'interno di un singolo stage, Azure Pipelines tenterà di eseguire quei tre job in parallelo su tre agent diversi, dando per scontato che tu abbia la capacità disponibile. Questo significa che i job non condividono file system locali o memoria. Se il job A compila il codice della tua applicazione, il job B non può semplicemente accedere ai binary compilati dal drive locale. Il job B sta girando su una macchina completamente diversa. Se hai bisogno che due processi condividano lo stesso spazio su disco locale in sequenza, devono essere inseriti nello stesso job. All'interno di un job, definisci gli step. Uno step è il più piccolo blocco costitutivo di una pipeline. È un'istruzione concreta, di solito un task o uno script. Dato che gli step vivono all'interno di un job specifico, vengono eseguiti tutti in sequenza esattamente sullo stesso agent. Lo step uno potrebbe essere un task per scaricare il tuo codice sorgente. Lo step due potrebbe essere uno script bash che fa girare il tuo compilatore. Dato che condividono lo stesso ambiente di esecuzione, lo step due ha accesso immediato e diretto ai file che lo step uno ha appena scaricato. Applica questo concetto alla strutturazione di una pipeline enterprise che esegue la build di un'applicazione, fa girare gli unit test e crea il package del risultato. Crei un singolo stage chiamato Continuous Integration. All'interno di questo stage, definisci due job separati per velocizzare l'esecuzione. Il job uno gestisce la build principale. I suoi step fanno il checkout del codice, eseguono il compilatore e creano il package del binary. Il job due gestisce l'analisi statica del codice e gli unit test standalone. Dato che si tratta di job separati all'interno dello stesso stage, vengono eseguiti in concomitanza su agent separati. Non si bloccano a vicenda, ma non condividono nemmeno un file system. Se il job due ha bisogno del binary creato dal job uno, devi istruire esplicitamente il job uno a pubblicare l'artifact nello storage della pipeline, e istruire il job due a scaricarlo. La struttura determina le capacità nella tua architettura di continuous integration. Usa gli stage per organizzare il tuo workflow in modo logico, ma affidati ai job per controllare esattamente dove e come la tua esecuzione scala su più macchine. Grazie per averci fatto compagnia. Spero tu abbia imparato qualcosa di nuovo.
3

Contesto di Esecuzione: Agents e Demands

4m 16s

Scopri come le Azure Pipelines eseguono il tuo codice utilizzando gli Agents. Trattiamo le differenze tra gli agent Microsoft-hosted e Self-hosted, e come utilizzare i Demands per instradare i job verso l'infrastruttura corretta.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 3 di 10. Ogni pipeline ha bisogno di potenza di calcolo, ma scegliere l'Execution Context sbagliato può raddoppiare silenziosamente i tempi della tua build. Magari scrivi un codice perfetto per la pipeline, ma se la tua build deve scaricare gigabyte di dipendenze da zero a ogni singola run, il tuo team perderà ore ad aspettare. Questo collo di bottiglia è esattamente il motivo per cui devi capire l'Execution Context, e in particolare gli Agent e i Demand. Per fare la build del codice o fare il deploy di software in Azure DevOps, ti serve un agent. Un agent è semplicemente un software installabile che si connette alla tua organizzazione Azure DevOps, resta in ascolto di nuovo lavoro ed esegue i job uno alla volta. Ogni agent gira su una macchina host, e in genere puoi scegliere tra due tipi di host. Puoi usare agent Microsoft-hosted, oppure agent self-hosted. Gli agent Microsoft-hosted sono la scelta di default per comodità. Chiedi una macchina, e Microsoft te ne fornisce una dal suo cloud pool. Non devi mai applicare patch al sistema operativo o aggiornare il software dell'agent. Ma questa comodità nasconde un'insidia che mette in difficoltà molti team. Ecco il punto chiave. Un agent Microsoft-hosted ti dà una virtual machine completamente nuova e pulita per ogni singola run della pipeline. Non si ricorda della tua ultima build. Quando il tuo job finisce, quella macchina viene distrutta per sempre. Se la tua build ha bisogno di una cache di pacchetti da svariati gigabyte, la scaricherà da zero dalla rete a ogni run, a meno che tu non aggiunga degli step espliciti di caching nella pipeline per salvare e ripristinare quei dati. Se vuoi evitare di scaricare il mondo ogni volta, o se la tua build deve passare dietro a un rigido firewall aziendale, usi gli agent self-hosted. Installi il software dell'agent sulla tua infrastruttura. Potrebbe essere un server nel tuo data center locale o una virtual machine persistente nel tuo cloud tenant. Dato che la macchina sopravvive tra una run e l'altra, le tue cache dei pacchetti, i Software Development Kit scaricati e i file di build incrementale restano esattamente dove li hai lasciati. Questo accelera drasticamente i tempi di esecuzione. Se cerchi una via di mezzo moderna, puoi dare un'occhiata ai Managed DevOps Pools. Questi funzionano come un'alternativa agli scale-set, in cui definisci immagini di base e dimensioni custom, e Azure gestisce il provisioning e lo scaling automatici. Questo copre cosa sono gli agent. Ora, come fa Azure DevOps a sapere quale agent usare per un job specifico? Questo si basa su un sistema di Capability e Demand. Ogni agent self-hosted riporta al server una lista di Capability. Molte di queste vengono scoperte automaticamente dal software dell'agent, come il tipo di sistema operativo o il path dei tool installati, come Node o Python. Puoi anche definire delle user capability custom, magari etichettando una macchina specifica perché ha una determinata scheda grafica. Nella definizione della tua pipeline, scrivi dei Demand per fare match con quelle Capability. Un Demand garantisce che il tuo job venga instradato solo a un agent che possiede esattamente la Capability che hai richiesto. Immagina uno scenario in cui stai compilando un'applicazione iOS. Compilare per iOS richiede Xcode, che a sua volta richiede strettamente hardware Apple. Supponi di avere un singolo pool di venti agent self-hosted, ma solo due di questi sono Mac Mini. Ti basta aggiungere un Demand per la Capability macOS al job della tua pipeline. Quando Azure DevOps valuta la run, filtra via tutte le macchine Windows e Linux nel pool, e instrada la tua build iOS direttamente a uno dei Mac Mini disponibili. La tua scelta dell'agent detta l'intera architettura della tua pipeline. Il Microsoft-hosted ti tira fuori dal business della manutenzione dei server al costo di doverti gestire lo state da solo, mentre il self-hosted scambia il mantenimento dell'infrastruttura con velocità pura e cache persistenti. Questo è tutto per questo episodio. Grazie per averci ascoltato, e continua a sviluppare!
4

Automatizzare il Workflow con i Triggers

3m 37s

Impara a far reagire automaticamente le tue pipeline agli eventi. Esploriamo i trigger di Continuous Integration (CI), i trigger di Pull Request (PR) e i trigger Scheduled per orchestrare cadenze di rilascio complesse.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 4 di 10. Potresti pensare che la tua pipeline venga eseguita solo quando qualcuno fa il push di un commit. Ma in un sistema maturo, le pipeline sono molto più proattive, ed eseguono diversi tipi di validazione in momenti completamente diversi. Stiamo parlando di automatizzare il workflow con i trigger. I trigger definiscono esattamente quali eventi causano l'esecuzione della tua pipeline. Il tipo più comune è il trigger di Continuous Integration, o CI. Un trigger CI si attiva automaticamente ogni volta che viene fatto il push del codice su un branch specificato. Nel file della tua pipeline, lo definisci usando un semplice blocco trigger. Puoi dirgli di ascoltare il main branch, ma di ignorare path di file specifici, come le cartelle della documentazione. Questo evita che la tua pipeline perda tempo a fare la build dell'applicazione quando qualcuno ha solo corretto un errore di battitura in un file di testo. Questo gestisce il codice che si sta già muovendo verso un branch. Ma di solito vuoi intercettare gli errori prima che avvenga il merge. Questo è il compito dei trigger di Pull Request. Un trigger PR si attiva quando viene aperta una pull request o quando vengono pushati nuovi commit su quella pull request esistente. Il suo scopo principale è proteggere il target branch validando il codice in entrata. Ecco il punto chiave. C'è una trappola comune in cui cadono gli sviluppatori con i trigger di PR. Quando una pull request attiva una pipeline, Azure Pipelines valuta la configurazione usando il file YAML che si trova nel source branch, non nel target branch. La logica che governa la validazione proviene dal feature branch stesso. Se apporti modifiche alla configurazione della pipeline nel tuo feature branch, quelle modifiche si applicano alla run della PR. I trigger di PR devono essere veloci. Se configuri un trigger di PR, dovresti usarlo per eseguire operazioni rapide, come unit test e code linting. Vuoi che gli sviluppatori ricevano feedback in pochi minuti. Ma alcune operazioni, come l'analisi statica approfondita o le scansioni di sicurezza pesanti, richiedono molto più tempo. Una scansione di sicurezza di due ore paralizzerà il tuo team se la associ a un trigger di PR. Questo ci porta al terzo tipo: gli scheduled trigger. Invece di reagire al movimento del codice, gli scheduled trigger eseguono le pipeline in base a un timer. Usano la sintassi cron standard per definire giorni e orari specifici per l'esecuzione della pipeline. Definisci un blocco schedules nel tuo file YAML, specifichi l'espressione cron ed elenchi i branch di cui vuoi fare la build. Puoi combinare questi trigger per creare un workflow efficiente. Durante il giorno, i tuoi trigger di PR eseguono unit test veloci sui feature branch per far procedere lo sviluppo. Nel frattempo, configuri uno scheduled trigger per avviare quella scansione di sicurezza di due ore ogni mezzanotte sul main branch. Puoi persino impostare lo scheduled trigger per essere eseguito solo se è stato fatto il merge di nuovi commit dalla notte precedente. Questo fa saltare completamente la run durante un weekend tranquillo, risparmiando sui costi di compute. L'utilizzo combinato di questi trigger ti consente di disaccoppiare il feedback rapido per gli sviluppatori dalla validazione profonda del sistema. I trigger non sono solo pulsanti di avvio; sono i controlli architetturali che decidono come e quando vengono spese le tue risorse di compute. Grazie per averci ascoltato — alla prossima.
5

Gestione dello Stato: Variables e Variable Groups

3m 44s

Padroneggia l'arte di passare stato e configurazione attraverso le tue pipeline. Questo episodio analizza le variabili di sistema predefinite, le variabili di pipeline personalizzate e come condividere le configurazioni tra i progetti utilizzando i Variable Groups.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 5 di 10. Hardcodare i nomi degli ambienti direttamente nei tuoi file YAML è un debito tecnico che aspetta solo di esplodere durante la tua prossima migrazione dell'infrastruttura. Quando questi nomi cambiano, non vuoi certo dover cercare tra decine di repository per aggiornarli. Lo State Management tramite Variables e Variable Groups risolve questo problema centralizzando la tua configurazione. La pipeline conosce già molto del suo execution context out of the box. Azure fornisce system variables predefinite per dare alla tua pipeline consapevolezza dell'ambiente senza alcun setup manuale. Ad esempio, se hai bisogno di sapere quale branch ha triggerato la run, usi Build punto SourceBranch. Se hai bisogno dell'ID univoco della run corrente, usi Build punto BuildId. Queste vengono popolate automaticamente e sono pronte da leggere. Quando hai bisogno di una configurazione custom, definisci delle inline variables. Le inserisci direttamente nel tuo file YAML sotto il blocco variables. Questo è perfetto per valori specifici di una singola pipeline, come un flag di build configuration o un file path locale. Mantiene la logica self-contained. Tuttavia, le inline variables falliscono quando scali. Prendi uno scenario in cui hai tre pipeline di microservizi separate. Tutte hanno bisogno di conoscere il nome dell'ambiente di deploy di destinazione e un set di URL di endpoint API condivisi. Se le definisci inline, ti stai ripetendo su tre repository. Se un endpoint cambia, hai tre pull request da fare. La soluzione è un Library Variable Group. Questo è un key-value store centralizzato mantenuto all'interno della Azure DevOps Library. Crei il gruppo una volta sola nella user interface, lo popoli con i nomi dei tuoi ambienti e gli endpoint API, e poi referenzi quel gruppo per nome nel blocco variables di tutte e tre le pipeline dei microservizi. Quando arriva il giorno della migrazione, aggiorni il Variable Group nel portale DevOps, e ogni pipeline usa all'istante i nuovi valori alla sua prossima run. Applichi il principio Don't Repeat Yourself, mantenendo la tua configurazione condivisa in un unico posto. Ecco il punto chiave. Il modo in cui chiami una variabile cambia quando Azure la valuta. Ci sono due sintassi principali, e mischiarle romperà la tua pipeline. La prima è la macro syntax, scritta come un segno del dollaro seguito da parentesi che racchiudono il nome della variabile. La macro syntax viene valutata a runtime. Azure sostituisce la variabile un attimo prima che il task specifico che la usa venga eseguito. La seconda è la template expression syntax, scritta come un segno del dollaro seguito da doppie parentesi graffe che contengono la parola variables punto e il nome della tua variabile. Le template expression vengono valutate a compile time, prima ancora che la pipeline inizi a girare. Se stai cercando di usare una variabile per decidere se uno stage debba essere eseguito o meno, o per definire un loop su una lista di job, devi usare la template expression syntax. La pipeline ha bisogno di quel valore in anticipo per costruire l'execution graph. Se un valore viene generato dinamicamente durante la run della pipeline da uno script, devi usare la macro syntax, perché il valore semplicemente non esiste a compile time. Padroneggia la differenza tra template expression a compile time e macro a runtime, ed eliminerai i più frustranti errori di parsing delle variabili nello sviluppo della tua pipeline. Per questo episodio è tutto. Alla prossima!
6

Proteggere i Secrets con Azure Key Vault

4m 06s

Smetti di memorizzare credenziali sensibili nel tuo strumento di CI/CD. Spieghiamo come integrare Azure Key Vault nelle Azure Pipelines per recuperare dinamicamente password, chiavi API e stringhe di connessione a runtime.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 6 di 10. Mascherare un secret nei log della tua pipeline non significa che sia sicuro se lo hai digitato direttamente nella tua configurazione CI/CD. Quando un amministratore di database ruota quella password, i tuoi deploy si rompono all'istante finché qualcuno non aggiorna manualmente la pipeline. Per risolvere questo problema, puoi recuperare le credenziali dinamicamente usando Azure Key Vault. Spesso definisci le variabili secret direttamente nell'interfaccia utente di Azure DevOps. Clicchi sull'icona del lucchetto, il testo scompare e presumi di essere al sicuro. Salvare i secret nell'interfaccia utente della pipeline crea una security posture frammentata. Se una policy aziendale impone di ruotare le credenziali ogni trenta giorni, trovare e aggiornare ogni variabile della pipeline in decine di progetti è un incubo operativo. Inoltre, perdi l'auditing centralizzato su chi o cosa ha avuto accesso a quei dati. L'approccio secure-by-design consiste nel recuperare i secret dinamicamente a runtime da un Key Vault aziendale. La pipeline non possiede mai il secret. Lo prende solo in prestito esattamente quando serve. Per riuscirci, usi il task della pipeline di Azure Key Vault. Per prima cosa, la pipeline ha bisogno dei permessi per guardare dentro il tuo vault. Configuri una service connection di Azure Resource Manager nel tuo progetto DevOps. Questa connessione si basa su un Service Principal o su una Managed Identity. Quindi concedi a quell'identità l'accesso esplicito in lettura ai secret nel tuo Key Vault usando la role-based access control di Azure o le access policy del vault. Ecco il punto chiave. La pipeline gira con questa identità, dimostrando chi è ad Azure prima di recuperare qualsiasi dato sensibile. Questo si adatta a un modello zero-trust. Non esistono credenziali permanenti nel tuo repository del codice o nelle definizioni della pipeline. Immagina una pipeline che recupera una connection string del database altamente sensibile subito prima di fare il deploy di un servizio backend. Nella definizione della tua pipeline, subito prima dello step di deploy, aggiungi il task Azure Key Vault versione due. Fornisci tre input principali a questo task. Primo, specifichi il nome della service connection della tua sottoscrizione Azure. Secondo, fornisci il nome del tuo Key Vault effettivo. Terzo, definisci una lista dei nomi dei secret specifici che vuoi scaricare. Puoi passare un asterisco come wildcard per scaricare tutto, ma i principi del least-privilege impongono di chiedere solo esattamente ciò di cui hai bisogno. Richiedi specificamente un secret chiamato production-database-connection. Quando la pipeline raggiunge questo step, fa una chiamata al vault. Se l'identità ha i permessi, il vault restituisce il secret. Il task prende quel valore sicuro e lo trasforma automaticamente in una variabile standard della pipeline. Il nome della nuova variabile della pipeline corrisponde esattamente al nome del secret nel vault. Il tuo prossimo step di deploy può ora fare riferimento a quella variabile per configurare il database, proprio come qualsiasi input di testo standard. Azure Pipelines registra anche questo valore scaricato come variabile secret in background. Se uno script stampa accidentalmente la connection string in console, il sistema la intercetta e sostituisce il testo effettivo con degli asterischi nei log. Il fetching dinamico garantisce che, quando il team del database aggiorna la password principale nel vault, la tua pipeline utilizzi automaticamente la nuova stringa alla sua primissima esecuzione successiva, con zero interventi manuali. Il tuo sistema di continuous delivery dovrebbe comportarsi come un corriere sicuro, che ritira la valigetta chiusa a chiave un attimo prima della consegna, anziché conservarne una copia permanente in deposito. Questo è tutto per questo episodio. Grazie per l'ascolto, e continua a sviluppare!
7

Controllo Dinamico: Conditions ed Expressions

3m 37s

Impara a rendere le tue pipeline intelligenti e reattive. Approfondiamo le Conditions e le Expressions personalizzate per controllare dinamicamente quali job e step eseguire in base ai valori delle variabili e agli esiti dei job precedenti.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 7 di 10. Le pipeline aziendali più affidabili non si limitano a girare ciecamente dall'inizio alla fine. Reagiscono dinamicamente quando qualcosa va storto, smantellando l'infrastruttura dopo un crash o saltando test suite pesanti durante un hotfix minore. Per costruire questo tipo di resilienza, hai bisogno del Controllo Dinamico: condizioni ed espressioni. Ogni job e step in Azure Pipelines ha una condizione associata, che tu la scriva esplicitamente o meno. Di default, il sistema applica una condizione integrata chiamata succeeded. Ciò significa che uno step viene eseguito solo se tutte le sue dipendenze precedenti sono terminate senza lanciare un errore. Se lo step uno fallisce, lo step due viene saltato automaticamente. Spesso si fraintende quando avvengono questi controlli. Una condizione valuta se uno step deve essere eseguito, e lo fa completamente prima che lo step o il job inizi. Uno step non può mai usare una condizione per valutare il proprio output interno. La condizione è il guardiano all'ingresso. Guarda lo stato della pipeline fino a quel preciso istante e decide se lo step può partire. A volte hai esplicitamente bisogno che un job giri quando uno step precedente fallisce. Prendi ad esempio un job di deploy che tira su un'infrastruttura di test temporanea. Se il deploy crasha a metà, il comportamento di default salta il resto della pipeline. I tuoi server temporanei rimangono online, bruciando silenziosamente il tuo budget cloud. Risolvi questo problema aggiungendo un job di cleanup dedicato alla fine della pipeline, ma cambi la sua condizione da succeeded a failed. Ora, questo job di cleanup ignora completamente le run completate con successo. Si sveglia per distruggere l'infrastruttura temporanea solo se i job di deploy principali crashano. Non sei limitato ai controlli di stato di base come succeeded, failed o always. Puoi scrivere espressioni personalizzate per valutare gli stati delle variabili e prendere decisioni di routing granulari. Azure Pipelines usa una sintassi funzionale per queste espressioni. Invece di scrivere simboli matematici, usi funzioni con nome. Se vuoi controllare se una variabile è uguale a un valore specifico, usi una funzione chiamata eq. Apri le parentesi, passi la variabile della pipeline che stai controllando, aggiungi una virgola e fornisci il valore che ti aspetti. Puoi combinare più controlli annidando queste funzioni. Supponiamo che tu abbia un job di release che dovrebbe girare solo se la pipeline è in succeeded e il branch corrente è main. Inizi con una funzione and. All'interno delle sue parentesi, passi due argomenti. Il primo argomento è la funzione succeeded. Il secondo argomento è la tua funzione eq, che confronta la variabile del source branch con la stringa di testo per il branch main. Il job di release verrà triggerato solo se entrambi gli statement restituiscono true. Usare le espressioni ti permette di costruire pipeline che si adattano al contesto della run. Prima di concludere, se vuoi supportare lo show, puoi cercare DevStoriesEU su Patreon, il che è sempre apprezzato. Ecco la parte che conta. La vera resilienza di una pipeline non deriva dal prevenire ogni possibile errore, ma dall'usare le condizioni per assicurarti che il tuo sistema sappia esattamente come gestire i fallimenti quando inevitabilmente si verificano. Grazie per l'ascolto. Alla prossima!
8

Riusabilità Enterprise: YAML Templates

4m 07s

Scala l'architettura della tua pipeline su decine di repository utilizzando gli YAML Templates. Impara la differenza tra 'Includes' ed 'Extends' e come applicare i requisiti di sicurezza a livello aziendale.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 8 di 10. Hai cinquanta microservizi e hai appena aggiornato la definizione di build per uno di questi. Ora devi copiare e incollare manualmente quel blocco YAML altre quarantanove volte. Se copi e incolli codice tra le pipeline, accumuli un enorme debito tecnico e rendi impossibili gli aggiornamenti di sicurezza globali. La soluzione è l'Enterprise Reusability: i template YAML. I template ti permettono di definire la logica della pipeline una sola volta e di riutilizzarla ovunque. In Azure Pipelines, i template funzionano in due modi completamente diversi: Include ed Extends. Un template Include si comporta esattamente come un'operazione di copia e incolla eseguita dal compilatore della pipeline. Prendi una sequenza comune, come l'installazione di un set di dipendenze o la pubblicazione di un artifact, la salvi come file YAML standalone, e poi la richiami dalla tua pipeline principale. Quando la pipeline viene eseguita, importa il contenuto di quel template esterno direttamente nel tuo job o stage attivo. Questo è utile per non ripeterti, ma lascia comunque allo sviluppatore il controllo completo sulla struttura della pipeline. È lui a decidere se, quando e dove includere il tuo template. Ecco il punto chiave. Quando un platform team centrale deve imporre delle regole, non usa gli Include. Usa gli Extends. Un template Extends ribalta completamente la struttura di controllo. Invece di avere la pipeline dello sviluppatore che importa pezzi di logica, la pipeline dello sviluppatore dichiara che estende un template centrale. Quel template centrale detta gli stage esatti, i job e lo scheletro generale dell'intera pipeline. Lo sviluppatore può passare le sue istruzioni specifiche solo negli slot che il template lascia esplicitamente aperti. Prendiamo come esempio una direttiva del security team. Richiedono che ogni microservizio faccia girare uno scanner di codice SAST, ovvero static application security testing, prima di compilare qualsiasi codice. Per imporre questa regola, scrivono un template Extends che definisce un job con due step. Il primo step è lo scanner SAST obbligatorio. Il secondo step è un placeholder per le azioni dello sviluppatore. Il file della pipeline del dev team non fa altro che puntare a questo template centrale e fornire i propri comandi di build specifici a quel placeholder. Il platform team ha la garanzia che lo scanner giri per primo, ogni singola volta, senza mai dover fare l'audit di cinquanta file YAML individuali. Per passare questi comandi o altre informazioni ai template, usi i Template Parameters. Spesso si confondono i parametri con le variabili, ma il loro comportamento è fondamentalmente diverso. Le variabili vengono valutate a runtime e in genere sono solo testo debolmente strutturato. I parametri vengono valutati a compile time. Prima ancora che la pipeline inizi l'esecuzione, Azure DevOps fa il parsing dei template e risolve tutti i parametri. Dato che questo avviene a compile time, i parametri offrono controlli di sicurezza rigorosi. Puoi definire tipi di parametro precisi, come boolean, number o una lista di step. Puoi imporre valori di default o limitare gli input a una lista predefinita di string consentite. Se uno sviluppatore prova a passare una string di testo a un parametro boolean, la pipeline si rifiuta di compilare. Questa strong typing previene i fallimenti a runtime e garantisce che il template si comporti esattamente come previsto dal team centrale. Forzando la struttura della pipeline a essere valutata e type-checked prima che inizi l'esecuzione, un template Extends funge da confine architetturale. Separa completamente ciò che gli sviluppatori creano da come l'organizzazione lo mette in sicurezza. Questo è tutto per questo episodio. Grazie per l'ascolto e continuate a sviluppare!
9

Indirizzare i Deployment con gli Environments

4m 11s

Eleva la tua pipeline dalla semplice 'esecuzione di codice' alla gestione di veri e propri deployment. Trattiamo il tipo Deployment Job, gli Environments e le strategie di deployment come runOnce e Canary.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 9 di 10. Puoi scrivere facilmente un pipeline job standard che esegue uno shell script per fare il push del codice su un server. Ma quando colpisce un bug critico e qualcuno ti chiede cosa sia andato esattamente in production martedì scorso, quel job standard non ti dà altro che i console log. Per avere un vero audit trail di cosa è stato deployato e dove, devi usare il Targeting Deployments con gli Environment. Un Environment in Azure DevOps è una collezione logica di risorse che usi come target per un deploy. Gli dai un nome come production o staging, e fa da ancora per il tracking. Invece di usare un pipeline job standard per fare il push del tuo codice, usi una keyword speciale chiamata deployment job. Quando colleghi un deployment job a un Environment, Azure DevOps traccia automaticamente i commit e i work item esatti che vengono deployati su quel target specifico. Ottieni una deployment history completa nell'interfaccia utente senza dover scrivere nessuna logica di logging extra. C'è una grande differenza nel modo in cui si comportano i deployment job rispetto ai job standard. Un job standard scarica automaticamente il tuo source code repository. Un deployment job no. Di default, salta completamente lo step di checkout. Questo spiazza un sacco di developer. Il motivo è semplice. Quando arrivi alla fase di deploy, dovresti deployare un artifact precompilato o una container image creata in uno stage di build precedente. In genere non ti serve il codice sorgente grezzo su un deployment runner. Se ti serve davvero il source repository, devi dire esplicitamente al deployment job di fare il checkout. Quando definisci un deployment job, non elenchi una sequenza piatta di task. Racchiudi questi task in una deployment strategy. La strategia più comune è run once. Come suggerisce il nome, esegue semplicemente i tuoi step di deploy in sequenza sull'Environment. Se ti serve qualcosa di più complesso, puoi usare la strategia canary. Canary ti permette di fare il deploy su una piccola percentuale dei tuoi server, monitorare gli errori, e poi fare un roll out graduale della nuova versione sul resto. Questo limita i danni di una bad release. All'interno di queste strategie, i tuoi task sono organizzati in lifecycle hook. Questo forza una struttura pulita. Per prima cosa, hai l'hook pre-deploy, dove magari inizializzi le risorse o esegui le migration del database. Poi arriva l'hook deploy, che fa il push della nuova versione della tua applicazione. Dopodiché, l'hook route-traffic gestisce lo spostamento delle request di rete verso la versione appena deployata. Infine, puoi usare post-route-traffic per eseguire degli health check o fare clean up delle vecchie risorse. Se qualcosa va storto, ci sono anche gli hook on-failure e on-success per gestire rollback o notifiche. Prendi uno scenario in cui usi la strategia run once per fare il push di una container image su un namespace Kubernetes. Nella tua pipeline, definisci un deployment job che ha come target il tuo Environment di production. All'interno della strategia run once, usi l'hook deploy per definire un task che prende il tuo container artifact buildato e applica il deployment manifest al cluster. Non hai bisogno di fare il checkout del repository perché la container image è già buildata e salvata nel tuo registry. Quando questa pipeline gira, i task vengono eseguiti e Azure DevOps registra l'azione. Dato che punta a un Environment, puoi aprire l'interfaccia, cliccare su production, e vedere esattamente quale commit ha triggerato la build dell'immagine, quale developer l'ha scritta, e che ha raggiunto con successo il cluster Kubernetes. Ecco il punto chiave. Passare da un job standard a un deployment job non cambia solo come è strutturata la tua pipeline. Trasforma la tua pipeline da uno script di automazione cieco a una deployment history completamente tracciabile. Grazie per averci seguito. Alla prossima!
10

Enterprise Gates: Approvals e Checks

4m 15s

Metti dei paletti ai tuoi deployment automatizzati. In questo episodio finale, esploriamo come configurare Approvals, Branch Control ed Exclusive Locks sui tuoi Environments per proteggere la produzione.

Download
Ciao, sono Alex di DEV STORIES DOT EU. Azure Pipelines, episodio 10 di 10. Non vuoi mai che una pipeline automatizzata faccia il push di una database migration massiccia e irreversibile in produzione un venerdì sera. Una pipeline completamente automatizzata è ottima finché non viene triggerata nel momento sbagliato o senza supervisione umana. È qui che gli Enterprise Gates, in particolare gli Approvals e i Checks, risolvono il problema. Prima di esaminare i Checks specifici, dobbiamo chiarire un equivoco comune. Gli Approvals e i Checks non sono definiti nel tuo file YAML della pipeline. Sono configurati nella UI di Azure DevOps, direttamente sulla risorsa stessa, come un Environment o una Service Connection. Questa distinzione è fondamentale. Se queste regole fossero nel file YAML, uno sviluppatore potrebbe modificare il file su un feature branch, rimuovere i Checks di produzione e bypassare i controlli. Posizionando la configurazione sulla risorsa, il resource owner applica le regole. Questo rende la tua compliance a prova di manomissione. Il codice della pipeline si limita a richiedere l'utilizzo della risorsa, e la risorsa decide se le condizioni di deploy sono soddisfatte. Applichiamo questo concetto a uno scenario concreto. Hai un Environment chiamato Production. Vuoi garantire la sicurezza della release e la compliance ITIL senza perdere la tua automazione. Innanzitutto, vuoi impedire i deploy durante il fine settimana. Sull'Environment Production nella UI, aggiungi un Check di Business Hours. Definisci la finestra temporale consentita, magari dal lunedì al giovedì, dalle nove alle diciassette nel tuo fuso orario locale. Se una pipeline tenta di fare il deploy al di fuori di questa finestra, si mette in pausa. Rimane in stato pending fino all'inizio delle business hours. Niente più database migration del venerdì sera. Poi, hai bisogno di un sanity check umano. Aggiungi un Check di Manual Approval e lo assegni a un gruppo specifico, come il team di QA. Quando la pipeline raggiunge lo stage di deploy per Production, si ferma. Parte un'email per il team di QA. Loro esaminano le modifiche e approvano o rifiutano esplicitamente la run nel portale di Azure DevOps. Solo dopo l'approvazione, la pipeline riprende. Puoi persino forzare la sequenza di valutazione, richiedendo che il Check di Business Hours venga superato prima che venga inviata la notifica di Manual Approval. Ora, devi garantire che il codice sperimentale non passi inosservato. Implementi il Branch Control. Aggiungi un Check che stabilisce che solo il branch main è autorizzato a puntare all'Environment Production. Se qualcuno triggera la pipeline da un feature branch, il Check fallisce automaticamente. Il deploy viene bloccato prima ancora di tentare la run. Infine, c'è il problema dei deploy concorrenti. Se due sviluppatori fanno il merge del codice a dieci minuti di distanza, potresti ritrovarti con due pipeline che tentano di aggiornare contemporaneamente la stessa infrastruttura di produzione. Il Check di Exclusive Lock previene questa race condition. Garantisce che solo una run della pipeline alla volta possa accedere all'Environment. La seconda pipeline aspetta semplicemente in coda fino al completamento della prima, garantendo una history di deploy pulita e sequenziale. Ecco il punto chiave. Gli Approvals e i Checks tolgono il potere di fare il deploy al codice della pipeline e lo affidano all'infrastructure owner, creando un confine sicuro e immutabile attorno ai tuoi sistemi critici. Dato che questo è l'ultimo episodio della nostra serie su Azure Pipelines, ti consiglio vivamente di spulciare la documentazione ufficiale di Microsoft e di provare queste configurazioni hands-on. Se vuoi suggerire argomenti per la nostra prossima serie, fai un salto su devstories dot eu. Questo è tutto per questo episodio. Grazie per l'ascolto, e continua a sviluppare!