Il provisioning dell'infrastruttura ha fatto molta strada. All'inizio significava installare fisicamente l'hardware. Poi, grazie alla virtualizzazione, è bastato qualche clic in un'interfaccia. In seguito i cloud provider hanno cominciato a esporre API REST per il provisioning dei servizi. Oggi è possibile definire in modo dichiarativo lo stato finale di un ambiente tramite codice: l'infrastructure as code è diventata realtà. Ne sono esempi Terraform, Cloudformation, i template ARM e così via.
Il vero nodo dell'infrastructure as code
L'infrastructure as code è ottima per la riproducibilità: riduce al minimo gli errori umani e aumenta l'immutabilità. In più, funge da documentazione. Terraform consente di effettuare il provisioning e di modificare l'infrastruttura in modo incrementale, salvando lo stato di esecuzione dopo ogni run. Quando però lo si mette davvero alla prova in un contesto enterprise, iniziano a emergere i suoi limiti.
Tanto per cominciare, introdurre logica con istruzioni if è complicato. Col tempo l'HCL di Terraform ha aggiunto il supporto a istruzioni if e cicli for, ma sembrano più una toppa che elementi di prima classe del linguaggio. I framework di infrastructure as code non offrono capacità di testing native. HCL, Cloudformation e i template di Azure Resource Manager hanno ciascuno la propria curva di apprendimento, e vincolano l'utente al rispettivo ecosistema.
Pulumi è un buon compromesso
All'estremo opposto ci sono gli SDK cloud disponibili per molti linguaggi di programmazione diffusi. Tutti i principali cloud provider offrono SDK di questo tipo, chiamati CDK, abbreviazione di cloud development kit. I CDK sono ottimi perché mettono a disposizione tutti i vantaggi di un linguaggio di programmazione; non hanno però un concetto di state management come quello di Terraform. La gestione dello stato è proprio ciò che rende le modifiche incrementali all'infrastruttura gestibili e prevedibili.
È qui che entra in gioco Pulumi, unendo i due mondi: offre sia un linguaggio di programmazione completo sia la gestione dello stato.
Per esempio, in JavaScript classico più condizioni if si scrivono così:
switch (ostype){
case 'linux':
Userdata = userdata
break;
case 'windows':
Userdata = windowsuserdata
break;
}
La stessa logica espressa in HCL diventa:
Linux = var.ostype == "linux" ? true : false
Windows = var.ostype == "windows" ? true : false
Come si vede, la leggibilità è nettamente migliore con la familiare sintassi JavaScript rispetto all'HCL di Hashicorp. HCL è un linguaggio specifico di dominio che non ha la flessibilità di un linguaggio general purpose. Per questo motivo, con un linguaggio general purpose è possibile portare maggiore intelligenza nell'infrastructure as code.
Pulumi porta con sé anche altri vantaggi tipici del ciclo di vita dello sviluppo software: test driven development, continuous integration, release versionate, package management e così via.
Software applicativo e software infrastrutturale possono finalmente convivere fianco a fianco: lo stesso repository git può ospitarli entrambi, scritti nello stesso linguaggio.
I concetti di Pulumi
Terraform ruota attorno a concetti come provider, module, state e così via. Anche Pulumi ha ripensato e semplificato i propri, come segue:
Stacks:
Gli Stack sono insiemi di risorse infrastrutturali correlate che condividono le stesse variabili d'ambiente. Sono assimilabili agli ambienti (dev, stage, prod) e ciascuno dispone di un proprio set di variabili, definite esclusivamente in "Pulumi.dev.yaml", "Pulumi.stage.yaml" e così via.
Projects:
Un Project è un raggruppamento logicamente isolato di risorse infrastrutturali che comprende più Stack. I Project possono essere mappati a team, iniziative o tipologie di infrastruttura (container, serverless, networking, ecc.). C'è ampio margine di interpretazione su quale tipo di raggruppamento sia più adatto a una determinata organizzazione.
Backends:
I Backend memorizzano lo stato di esecuzione di Pulumi in un sistema di storage persistente. Possono essere di diversi tipi:
1. Service backend: Pulumi cloud (SAAS) o Pulumi self-hosted. I Service backend hanno il vantaggio di mantenere snapshot dell'infrastruttura a intervalli regolari, agevolando il rollback e il recupero da errori critici durante il provisioning.
2. Object storage gestito in autonomia (AWS S3, GCP GCS, Azure blob, ecc.).
Providers
Pulumi è in grado di effettuare il provisioning di infrastrutture e servizi su diverse piattaforme. Al momento sono disponibili provider per AWS, GCP, Azure, Kubernetes, Cloudflare e molti altri.
Appendice
Tabella comparativa

Prossimamente
Nella seconda parte di questo articolo approfondiremo le funzionalità avanzate di Pulumi che permettono ai team autonomi di effettuare il provisioning e di mantenere la propria infrastruttura insieme alle relative applicazioni. Esamineremo anche una codebase capace di effettuare il provisioning di cluster EKS su AWS — cluster EKS che vanno oltre il classico "hello world" e includono elementi di hardening e production readiness. Restate sintonizzati!
Per restare in contatto, seguiteci sul DoiT Engineering Blog, sul canale LinkedIn di DoiT e sul canale Twitter di DoiT. Per scoprire le opportunità di carriera, visitate https://careers.doit-intl.com.
Sul piano della semantica del linguaggio, le differenze tra HCL e un linguaggio general purpose potrebbero non essere così marcate. Ma se si deve scegliere tra un linguaggio di programmazione general purpose maturo e ben rodato e un linguaggio dichiarativo proprietario, nuovo e specifico di dominio, per ottenere lo stesso risultato, perché optare per quello meno conosciuto? Sia HCL sia un linguaggio general purpose svolgono il compito in modo più che adeguato. Ma alla luce degli ecosistemi consolidati attorno ai linguaggi general purpose e dei talenti disponibili sul mercato, scegliere un framework come Pulumi al posto di Terraform è una decisione che ha senso.