Se avete già lavorato allo sviluppo di un’applicazione, avrete sicuramente sentito parlare del termine “variabili d’ambiente”. Le variabili d’ambiente sono utilizzate per memorizzare i segreti dell’applicazione e i dati di configurazione, che vengono recuperati dall’applicazione in esecuzione quando necessario.

Le variabili d’ambiente aggiungono dinamicità alla vostra base di codice statica; si può passare da una risorsa interna a una esterna in base al valore della variabile d’ambiente passata all’applicazione.

Questo articolo vi fornirà una panoramica sulle variabili d’ambiente. Scoprirete alcuni dei modi più popolari per creare e gestire le variabili d’ambiente, e capirete quando usarle. Alla fine di questo articolo, sarete in grado di utilizzare con efficacia e sicurezza le variabili d’ambiente nelle vostre applicazioni.

Senza ulteriori indugi, iniziamo!

Cos’è una Variabile d’Ambiente?

Come già accennato nella nostra introduzione, le variabili d’ambiente sono variabili disponibili per il vostro programma/applicazione in modo dinamico durante l’esecuzione. Il valore di queste variabili può provenire da diverse fonti: file di testo, secret manager di terze parti, script di chiamata, ecc.

L’aspetto importante è che il valore di queste variabili d’ambiente non è codificato nel vostro programma. Sono veramente dinamiche e possono essere modificate in base all’ambiente in cui il programma viene eseguito.

Tipi di Variabili d’Ambiente

Esistono tre tipi principali di variabili d’ambiente in un sistema informatico basato su Windows, e ognuno di essi ha i suoi casi d’uso. Vediamoli uno per uno.

1. Variabili d’Ambiente di Sistema

Le variabili d’ambiente di sistema risiedono nella parte superiore della root di sistema e sono le stesse per tutti i processi in esecuzione sotto tutti i profili utente del sistema stesso. Di solito sono impostate dal sistema operativo o dall’amministratore di sistema, e raramente è necessario modificarle.

Uno degli usi più comuni di una variabile d’ambiente di sistema è l’impostazione di una variabile PATH per un pacchetto/libreria globale da utilizzare da tutti gli utenti del sistema.

2. Variabili d’Ambiente Utente

Le variabili d’ambiente utente sono quelle locali di un profilo utente nei sistemi Windows. Queste variabili sono utilizzate per memorizzare informazioni specifiche dell’utente, come il percorso di un’installazione locale di librerie che non devono essere utilizzate da tutti gli utenti, valori specifici di programmi installati solo per utenti specifici, ecc.

Non è necessario che l’amministratore del sistema apporti modifiche a queste variabili; potete farlo voi stessi come utenti. Queste variabili sono utili per implementare modifiche locali al sistema senza influenzare gli altri utenti.

3. Variabili d’Ambiente Runtime/Process

Le variabili d’ambiente del runtime si restringono ulteriormente solo al runtime o al processo a cui sono associate. Di solito sono impostate dal processo genitore che crea il nuovo processo e sono accompagnate dalle variabili d’ambiente del sistema e dell’utente.

È possibile utilizzare lo scripting del terminale per creare e memorizzare queste variabili al volo. Le variabili di runtime di solito non sono permanenti, a meno che non siano state create tramite script, e devono essere definite ogni volta che si avvia un nuovo processo.

Variabili d’ambiente nei sistemi Unix

A differenza dei sistemi Windows, i sistemi basati su Unix non hanno tre livelli di variabili d’ambiente. In questi sistemi, tutto è memorizzato in un oggetto var e può essere accessibile/modificato dal programma in esecuzione.

Se si desidera impostare alcune variabili d’ambiente come predefinite da caricare ogni volta che un programma viene eseguito sul sistema, è necessario definirle in file come .~/bashrc o ~.profile che vengono caricati all’avvio del sistema.

Variabili d’Ambiente e Pseudo Variabili d’Ambiente

Nei sistemi Windows e DOS è disponibile una linea separata di variabili d’ambiente dinamiche, note come pseudo-variabili d’ambiente. Non si tratta di coppie di chiavi e valori assegnati staticamente, ma di riferimenti dinamici che restituiscono vari valori quando vengono interrogati.

Mentre è possibile assegnare un valore a una variabile d’ambiente manualmente utilizzando il comando SET o il suo equivalente, non si possono assegnare valori alle pseudo variabili d’ambiente. Esiste un elenco fisso di queste variabili che si possono utilizzare nel codice per semplificare il proprio lavoro. Alcuni casi d’uso popolari sono %CD% per la directory corrente e %TIME% per l’ora corrente.

Perché Dovreste Usare le Variabili d’Ambiente?

Ora che avete chiaro cosa sia una variabile d’ambiente e i vari tipi esistenti, è il momento di sapere perché dovreste usarle quanto più possibile nelle vostre applicazioni.

Separation of Concerns

Uno dei motivi più importanti per cui dovreste usare le variabili d’ambiente nelle applicazioni è quello di aderire a un principio di progettazione molto diffuso e utile: la “separation of concerns”. Questo principio afferma che i programmi informatici dovrebbero essere divisi in sezioni distinte per poterli gestire in modo efficiente. Ogni sezione dovrebbe essere basata su uno dei concern principali del programma e l’accoppiamento tra queste sezioni dovrebbe essere minimo.

La configurazione dell’applicazione può essere considerata uno di questi concern e quindi deve essere separata dal programma principale. Uno dei modi migliori per farlo è memorizzarla in un file esterno e iniettarla quando serve. Le variabili d’ambiente aiutano a isolare i dati critici di configurazione dell’applicazione utilizzando file env o archivi di variabili remoti. In questo modo, gli sviluppatori riceveranno solo le informazioni di cui hanno bisogno.

Mantenere Set di Configurazioni Indipendenti tra i Vari Ambienti

Oltre a isolare le configurazioni dell’applicazione dal codice sorgente, è necessario anche essere in grado di passare facilmente da un set di dati di configurazione all’altro. Se si sceglie di codificare i valori di configurazione dell’app nel codice sorgente, può diventare quasi impossibile sostituirli in base a condizioni esterne come gli ambienti di distribuzione.

L’uso delle variabili d’ambiente aiuta a disaccoppiare i dati di configurazione dal codice e a standardizzare il modo in cui queste informazioni vengono fornite alla vostra applicazione, consentendovi di modificare/scambiare al volo le informazioni fornite.

Proteggere i Segreti

I segreti della vostra app rientrano tra le informazioni sensibili. Se le persone sbagliate ci mettono le mani sopra, possono accedere all’architettura interna della vostra app e alle risorse di terze parti. Esempi comuni sono le chiavi AWS e i dettagli degli account di sistema. L’accesso non autorizzato a queste chiavi può portare alla perdita di denaro e di dati dell’applicazione. Gli hacker possono persino arrivare a impedire il normale funzionamento dell’applicazione.

Per questo motivo è fondamentale che proteggiate questi segreti: se lasciati in giro nella base di codice, tutti gli sviluppatori possono accedervi. Se non seguite metodi di offuscamento del codice adeguati, le vostre applicazioni possono essere sottoposte a reverse engineering e le chiavi contenute nel codice recuperate. L’isolamento di questi segreti attraverso le variabili d’ambiente può evitare che si verifichino questi scenari.

Esempi di Utilizzo delle Variabili d’Ambiente

Ora che avete un’idea chiara di come funzionano le variabili d’ambiente e di come usarle in modo efficace, ecco alcuni scenari frequenti in cui usare le variabili d’ambiente:

  • Tipo di ambiente: Le variabili d’ambiente sono spesso utilizzate per memorizzare il nome dell’ambiente in cui l’applicazione è in esecuzione. La logica dell’applicazione può utilizzare questo valore per accedere al giusto set di risorse o per abilitare/disabilitare determinate funzionalità o sezioni dell’applicazione.
  • Nome di dominio: Il nome di dominio di un’applicazione può variare in base all’ambiente in cui si trova. Isolarlo vi permette di modificare facilmente il nome di dominio dell’applicazione senza doverlo cercare in tutto il codice.
  • URL API: Ogni ambiente della vostra applicazione può avere API distribuite anche in ambienti diversi.
  • Chiavi private: Le chiavi dei servizi e delle risorse a pagamento devono essere isolate dal codice sorgente dell’app per evitare che finiscano accidentalmente nelle mani sbagliate.
  • Numeri di account di servizio, ecc.: è possibile variare altre informazioni specifiche del sistema, come numeri di account di servizio, keytab, ecc. in base all’ambiente dell’app per la gestione e il monitoraggio delle risorse.

Come Memorizzare le Variabili d’Ambiente

Ora che il perché le variabili d’ambiente sono importanti è più chiaro, è il momento di vedere come memorizzarle e accedervi nella propria applicazione. Di seguito sono illustrati tre modi diversi ma molto diffusi di gestire le variabili d’ambiente in un’applicazione.

Usare i File .env

I file .env sono senza dubbio il modo più semplice e diffuso di gestire le variabili d’ambiente. L’idea è semplice: si memorizzano le variabili d’ambiente in un file chiamato .env nella root del proprio progetto. L’applicazione cerca le variabili in questo file e le carica per utilizzarle durante l’esecuzione. Ecco come si presenta un tipico file .env:

VAR_UNO=SOME_KEY_HERE
VAR_DOS=SOME_OTHER_KEY_HERE

I file.env permettono anche di definire degli insiemi di variabili d’ambiente e di accedervi in base all’ambiente di esecuzione della propria applicazione o ad altri fattori. Invece di salvare il file semplicemente come .env, è possibile creare più di un file e conservarli come .env.dev e .env.prod. All’interno di questi file, si possono definire gli stessi set di variabili ma con valori diversi, a seconda dell’ambiente.

Modello di Esempio

Quando si lavora con i file .env, non è consigliabile aggiungerli al sistema di controllo della versione (ne parleremo più avanti). Per questo motivo, dovreste definire un “.env.template” nel vostro progetto in modo che gli sviluppatori possano seguire il modello e creare un file .env a livello locale.

Ecco come potrebbe apparire un file .env.template:

VAR_UNO= # Your value here
VAR_DOS= # Your value here

Non è necessario che segua delle convenzioni, purché sia chiaro per il team di sviluppo. Per semplificare questo processo, si possono anche utilizzare pacchetti come env-template.

I Vantaggi

Ecco alcuni motivi per cui dovreste prendere in considerazione l’utilizzo dei file .env per gestire le variabili d’ambiente nella vostra applicazione.

Semplice da Usare

Questo metodo è il più semplice tra le tecniche di gestione delle variabili d’ambiente. Tutto ciò che dovete fare è creare un file di testo semplice che contenga i vostri segreti e memorizzarlo nella root del progetto.

Cambiare ambiente è semplice come cambiare il file env stesso. Si possono memorizzare più file con i nomi .env.dev, .env.prod, .env.uat, ecc. e configurare il codice sorgente per accedere a questi file in base all’ambiente in cui viene eseguito.

Accesso Locale

I file .env si possono configurare facilmente in un ambiente di sviluppo locale. A differenza degli strumenti di gestione delle variabili nativi della piattaforma, non è necessario distribuire l’applicazione per sfruttare la funzionalità delle variabili d’ambiente. Rispetto ai secret manager, i file .env sono più facili da configurare localmente e non c’è alcuna dipendenza dalla rete per accedere ai segreti dell’applicazione.

Supporto Open Source

Esistono numerosi pacchetti open-source che aiutano a caricare e gestire i segreti delle app dai file env. Non è necessario dipendere da servizi a pagamento, né le opzioni sono limitate per quanto riguarda la gestione dei segreti delle app. Esiste un’ampia gamma di librerie open-source di terze parti che aiutano a gestire i file env. Alcuni esempi popolari e utili sono dotenv, env-template e cross-env.

Contro

Ecco alcuni svantaggi dei file env che dovreste conoscere prima di utilizzarli nei vostri progetti.

Formattazione

I file .env memorizzano i segreti della vostra applicazione sotto forma di coppie chiave-valore. Il formato abituale per memorizzare le variabili d’ambiente in un file .env è:

Key1=Value1

Dovrete attenervi rigorosamente a questo formato affinché la vostra app possa leggere con successo i segreti dell’applicazione. Se si commette un piccolo errore in mezzo a decine o centinaia di righe di variabili d’ambiente, l’intero file potrebbe non essere analizzato e il programma potrebbe restituire errori non correlati. Il fatto che ci sia un errore di parsing nel file .env potrebbe non essere nemmeno evidenziato. Ecco perché dovete fare attenzione quando utilizzate i file .env.

Rischio di Perdita Accidentale di Segreti Durante la Condivisione e l’Archiviazione

Poiché i file .env sono file di testo semplice, sono vulnerabili all’esposizione accidentale quando vengono archiviati su un disco rigido condiviso o inviati tramite una rete non protetta. Per questo motivo è necessario prestare particolare attenzione a non far trapelare i segreti della vostra app quando li memorizzate con i file .env.

Utilizzare l’Archiviazione delle Variabili Nativa della Piattaforma

Un’altra opzione popolare per memorizzare le variabili d’ambiente è quella di affidarsi all’archiviazione delle variabili della piattaforma di distribuzione. La maggior parte degli ambienti di distribuzione, come Heroku, AWS, Netlify e così via, offrono agli utenti uno spazio per caricare i segreti che vengono poi iniettati nel runtime dell’applicazione. È possibile consultare la documentazione della piattaforma di deployment per sapere se la supporta e come iniziare a utilizzarla.

Ecco una rapida occhiata allo strumento di gestione delle variabili d’ambiente di Netlify:

Strumento di gestione delle variabili d'ambiente di Netlify.
Strumento di gestione delle variabili d’ambiente di Netlify.

Pro

Ecco perché dovreste prendere in considerazione l’utilizzo di soluzioni di archiviazione delle variabili native della piattaforma.

Altamente Sicura

Poiché questa opzione è gestita interamente dalla piattaforma di distribuzione, è sicuramente più sicura rispetto alla memorizzazione dei segreti in un file di testo. È possibile controllare chi può accedere allo strumento di gestione delle variabili ed essere certi che i segreti non verranno mai inviati accidentalmente al VCS.

Facile da Aggiornare

Aggiornare le variabili d’ambiente quando sono memorizzate in modo indipendente è più semplice: non è necessario modificare il codice sorgente e crearne una nuova versione. Basta semplicemente cambiare i valori nella piattaforma e ricostruire il progetto. Il progetto riceverà i nuovi valori al successivo avvio.

Anche la formattazione non è più un problema, poiché la maggior parte dei gestori di distribuzione specifici per la piattaforma sottopongono le chiavi a lintering man mano che vengono inserite. In casi come quello di Netlify, è possibile inserire i segreti in una forma pre-formattata, eliminando le possibilità di commettere errori di formattazione.

Consente la Collaborazione

Poiché le piattaforme di distribuzione sono accessibili a tutto il team, è facile condividere i segreti con le persone giuste senza dover inviare file di testo via internet. È inoltre possibile controllare chi può accedere al variable manager (nella maggior parte dei casi) e usarlo come archivio centrale per i segreti delle app.

Contro

Anche se gli strumenti di gestione delle variabili nativi della piattaforma sembrano essere la soluzione che fa per voi, ci sono alcuni aspetti da tenere a mente prima di sceglierli.

Dipendono dalla Piattaforma

Come dice il loro nome, sono altamente specifici per la piattaforma che si sta utilizzando. In alcuni casi, la piattaforma di distribuzione potrebbe non offrire questo servizio. Cambiare la piattaforma di distribuzione per avere accesso a questo servizio potrebbe non essere la decisione migliore.

Non uniforme

Poiché sono offerti e gestiti completamente dalla piattaforma di distribuzione, questi servizi possono essere altamente non uniformi. Spostare le variabili da una piattaforma all’altra può essere problematico. Non si può nemmeno pensare che tutte le piattaforme di distribuzione offrano la possibilità di importare/esportare le variabili d’ambiente. Anche se la maggior parte lo fa, è tutto nelle mani della piattaforma. Se si ha un lungo elenco di variabili d’ambiente, ci sono molte probabilità di incorrere in un piccolo vendor lock-in.

Nessun Supporto Locale

Sebbene questi servizi siano ottimi per accedere alle variabili d’ambiente nelle distribuzioni della vostra applicazione, è raro che si possano utilizzare durante lo sviluppo dell’applicazione in locale. Nella maggior parte dei casi, dovrete ricorrere alla gestione dei file .env locali. Pur raggiungendo lo scopo, questa soluzione complica inutilmente l’intera configurazione.

Utilizzare i Secret Manager

La terza opzione, attualmente in fase di sviluppo, è quella di utilizzare dei secret manager dedicati. I secret manager sono servizi di terze parti che permettono di isolare completamente i segreti dell’applicazione dal codice sorgente o dalla distribuzione e di recuperarli quando necessario attraverso connessioni di rete sicure.

I Vantaggi

Ecco alcuni dei vantaggi che i secret manager offrono rispetto ad altri metodi di gestione dei segreti.

Altamente Sicuro

Dal momento che i segreti sono archiviati in un servizio completamente isolato, si può essere certi che molto probabilmente non verranno mai divulgati accidentalmente mentre li si condivide con i colleghi o tramite i commit del controllo di versione. La piattaforma di terze parti si occupa di tenere al sicuro i segreti e di solito ha degli SLA piuttosto rigidi per quanto riguarda la sicurezza dei dati.

Anche quando si accede ai segreti dall’interno della propria applicazione, la maggior parte dei secret manager fornisce il proprio codice client in grado di recuperare in modo sicuro e di consentire l’accesso ai segreti quando necessario.

Uniforme in Tutti gli Ambienti

Poiché i segreti sono ora indipendenti dalla base di codice e dagli ambienti di distribuzione, si potrà godere di un’uniformità tra gli ambienti. Non si dovranno prendere provvedimenti particolare per l’onboarding di nuovi sviluppatori o adottare misure particolari prima di mettere in produzione la vostra applicazione: la maggior parte di questi aspetti sono semplificati o gestiti dal secret manager.

Contro

Anche se i secret manager sembrano essere la migliore soluzione possibile per la gestione delle variabili d’ambiente, hanno i loro limiti.

Costi

La gestione delle variabili d’ambiente è parte delle attività interne ai progetti da molto tempo, e la maggior parte delle piattaforme di distribuzione fornisce questa funzione gratuitamente, poiché non prevede costi aggiuntivi.

Tuttavia, poiché i secret manager sono servizi completamente indipendenti, hanno un proprio costo operativo. Di conseguenza, gli utenti devono sostenere questo costo quando utilizzano questi servizi.

Fasi Iniziali della Tecnologia

Poiché la tecnologia è piuttosto nuova, non si può essere sicuri di quanto sarà adottata dal settore in futuro. Sebbene i secret manager siano molto promettenti in termini di sicurezza e facilità di gestione, il fattore costo e le preoccupazioni legate alla gestione dei dati potrebbero portare a un’adozione piuttosto lenta della tecnologia.

Come Lavorare con le Variabili d’Ambiente

Ora che avete compreso il concetto di variabili d’ambiente e i modi disponibili per implementarle in un’applicazione, vediamo come lavorarci tramite il terminale e nelle applicazioni basate su Node.js.

Variabili d’Ambiente nel Terminale

Poiché le variabili d’ambiente sono specifiche per i processi, è possibile impostarle e cancellarle tramite il terminale in modo che vengano trasmesse ai processi generati dal terminale.

Trovare i Valori delle Variabili

Per visualizzare l’elenco delle variabili d’ambiente nel terminale, basta eseguire i seguenti comandi, specifici per sistema operativo.

Su Windows:

set

Su Linux o MacOS:

env

Questa operazione stamperà un elenco di tutte le variabili d’ambiente disponibili nel terminale in esecuzione.

Impostare Nuove Variabili

Per impostare nuove variabili tramite il terminale, è sufficiente eseguire i seguenti comandi.

Su Windows:

set "VAR_NAME=var_value"

Su Linux o MacOS:

VAR_NAME=var_value

Cancellare le Variabili

Per eliminare una variabile d’ambiente, basta eseguire i seguenti comandi.

Su Windows:

set "VAR_NAME="

Su Linux o MacOS:

unset VAR_NAME

Tenete presente che i metodi sopra descritti servono solo a creare/eliminare le variabili d’ambiente per la sessione corrente del terminale.

Variabili d’ambiente in Node.js

JavaScript è uno dei linguaggi di programmazione più popolari al momento. È ampiamente utilizzato sia per creare applicazioni back-end che front-end, il che lo rende uno dei linguaggi di programmazione più versatili.

Node.js è uno dei framework JS più utilizzati per la creazione di applicazioni backend. Vediamo come gestire facilmente le variabili d’ambiente nelle applicazioni basate su Node.js.

Accedere Direttamente alle Variabili d’Ambiente

Node.js fornisce un riferimento alle variabili d’ambiente del processo corrente tramite process.env. È possibile visualizzare le variabili d’ambiente disponibili stampando questo oggetto nella console.

Stampa dell'oggetto process.env.
Stampa dell’oggetto process.env.

Questo oggetto conterrà le variabili disponibili per il processo Node in esecuzione. È possibile aggiungere nuove variabili dichiarandole prima dell’esecuzione dell’applicazione, in modo simile a questo:

VAR_UNO=SOMETHING node index.js
Stampa dell'oggetto process.env dopo aver aggiunto una nuova variabile.
Stampa dell’oggetto process.env dopo aver aggiunto una nuova variabile.

Come si può notare, la nuova variabile viene aggiunta all’oggetto process.env. Tuttavia, non è possibile accedere a nessuna variabile definita in un file .env tramite questo metodo. Per farlo, è necessario utilizzare un pacchetto come dotenv per caricare il file .env in fase di esecuzione.

Usare il Pacchetto dotenv per Accedere ai File .env

Il pacchetto dotenv aiuta a caricare le variabili d’ambiente memorizzate nei file .env nella root del progetto. Il suo utilizzo è semplice: si comincia con l’installazione eseguendo il seguente comando:

npm i [email protected]

Successivamente, dovrete aggiungere la seguente riga di codice all’inizio del codice della vostra applicazione per inizializzare il pacchetto:

require('dotenv').config()

Ecco fatto! Ora i segreti memorizzati in un file .env nella root del progetto saranno caricati nell’oggetto process.env non appena l’applicazione si avvia. Vedremo questo metodo in azione più avanti nel seguente tutorial.

Tutorial sulle Variabili d’Ambiente

Il modo migliore per capire un concetto tecnico è vederlo in azione. Ecco un rapido tutorial che vi aiuterà a iniziare a conoscere le variabili d’ambiente e ad apprenderne l’uso in dettaglio.

Nella seguente guida vi mostreremo come utilizzare le variabili d’ambiente attraverso tutti e tre i modi che abbiamo menzionato in precedenza: i file.env, i variable manager nativi della piattaforma e i secret manager. Tutti questi modi hanno in comune il punto di partenza, ovvero la creazione di un progetto Node.js di base.

Primo: Creare un Progetto Node.js

Per iniziare, assicuratevi di aver installato Node.js sul vostro sistema. Una volta installato sul sistema, avrete accesso a npm (abbreviazione di Node Package Manager). npm vi aiuta a installare i pacchetti node dal registro globale npm tramite la riga di comando. Vi sarà utile per installare i pacchetti relativi al nostro progetto di prova.

Quindi, aprite un terminale e create una nuova directory. Inizializzate un nuovo progetto Node al suo interno:

mkdir my-app
cd my-app
npm init

Continuate a premere invio durante le domande in arrivo per accettare le opzioni predefinite. Una volta fatto, il terminale avrà un aspetto simile a questo:

Creazione di un nuovo progetto.
Creazione di un nuovo progetto.

Ora potete aprire questo progetto utilizzando un IDE come Visual Studio Code o IntelliJ IDEA.

Create un nuovo file nella cartella principale del progetto e salvatelo con il nome index.js. Questo sarà il punto di partenza della vostra applicazione. Successivamente, installate Express per creare e testare rapidamente i server REST:

npm i express

Una volta installato Express, incollate il seguente pezzo di codice nel file index.js:

const express = require("express")

const app = express()

app.get("/", (req, res) => {
   res.send("Hello world!")
})

app.listen(8080);

Questo è uno snippet iniziale per un endpoint di base “Hello World” utilizzando Node.js ed Express. Eseguite il seguente comando sulla riga di comando:

node index.js

Questo avvierà la vostra applicazione node + express. Se navigate su http://localhost:8080 nel browser web, otterrete un risultato simile:

Stampa Hello World!.
Stampa Hello World!.

Questo indica che avete configurato correttamente la vostra app! Il passo successivo consiste nell’aggiornare l’applicazione per utilizzare le variabili d’ambiente. Aggiornate il codice in index.js in modo che corrisponda al seguente frammento:

const express = require("express")

const app = express()

app.get("/", (req, res) => {
  
   // the responseMessage object extracts its values from environment variables
   // If a value is not found, it instead stores the string "not found"
   const responseMessage = {
       environment: process.env.environment || "Not found",
       apiBaseUrl: process.env.apiBaseUrl || "Not found"
   }

   res.send(responseMessage)
})

app.listen(8080);

Invece di inviare un messaggio “Hello world!” nella risposta, ora invieremo un oggetto JSON che contiene due informazioni:

  • environment: Indica l’ambiente attuale in cui l’applicazione è distribuita
  • apiBaseUrl: Riporta l’URL di base di un’ipotetica API. Cambieremo il valore di questo URL in base all’ambiente in cui viene distribuita l’app.

Nel caso in cui non sia possibile accedere alle variabili d’ambiente, l’oggetto conterrà “Not found” (non trovato) come valori per le due chiavi descritte sopra. Prima di procedere, rieseguite il comando node index.js e riceverete il seguente output:

Stampa dei valori predefiniti delle variabili di <code>env</code>.
Stampa dei valori predefiniti delle variabili di env.

Questo indica che la vostra applicazione non è in grado di accedere alle variabili d’ambiente. Inoltre, non abbiamo nemmeno definito i valori di queste variabili. Nelle prossime sezioni vedremo i vari modi per farlo.

Tipo 1: Aggiungere le variabili d’ambiente tramite i file env

Iniziamo con il metodo più semplice per aggiungere variabili d’ambiente: i file env. Nella root del progetto, create un nuovo file chiamato .env e inserite il seguente codice:

environment=DEV
apiBaseUrl=http://dev.myApi.com:8080/v1

Successivamente, riavviate l’applicazione eseguendo nuovamente il comando node index.js e verificate l’output:

Stampa dei valori delle variabili di <code>env</code>.
Stampa dei valori delle variabili di env.

Vedrete che l’output rimane invariato. Questo perché, anche se avete definito il valore delle variabili d’ambiente, non avete indicato all’applicazione dove trovarle. È qui che pacchetti come dotenv ci vengono in aiuto.

Eseguite il seguente comando per installare dotenv:

npm i [email protected]

Per iniziare a utilizzare dotenv nel vostro codice, aggiungete il seguente codice alla riga 2 del vostro index.js:

require('dotenv').config()

Successivamente, riavviate l’applicazione e controllate l’output:

Stampa dei nuovi valori delle variabili di <code>env</code>.
Stampa dei nuovi valori delle variabili di env.

Come potete vedere, i valori delle variabili d’ambiente sono stati caricati dal file .env!

Ora, per rendere le cose più interessanti, rinominiamo il nostro file .env in .env.dev e creiamo un altro file con il nome .env.staging. Incollate il seguente pezzo di codice nel nuovo file:

environment=STAGING
apiBaseUrl=http://staging.myApi.com:3000/v1

Una volta terminato, sostituite la riga 2 del file index.js con il seguente codice:

require('dotenv').config({
   path: "STAGING" === process.env.NODE_ENV?.toUpperCase() ? './.env.staging' : './.env.dev'
})

console.log(process.env.NODE_ENV)

Ciò che è cambiato qui è che ora stiamo istruendo il pacchetto dotenv a recuperare il contenuto delle variabili d’ambiente da uno dei due file disponibili in base a un’altra variabile d’ambiente chiamata NODE_ENV. Da dove proviene il valore di questa variabile d’ambiente? Dal vostro terminale.

Per testare questa configurazione, eseguite la vostra applicazione con il seguente comando:

NODE_ENV=DEV node index.js

Se ora andate su localhost:8080, noterete la seguente risposta:

Stampa dei valori env per l'ambiente dev.
Stampa dei valori env per l’ambiente dev.

Ora, chiudete l’applicazione in esecuzione ed eseguitela di nuovo con il seguente comando:

NODE_ENV=STAGING node index.js

Collegandovi a localhost:8080 otterrete la seguente risposta:

Stampa dei valori env per l'ambiente di staging.
Stampa dei valori env per l’ambiente di staging.

Ecco come potete utilizzare i file .env per accedere a diversi set di variabili in base a condizioni esterne. La condizione esterna in questo caso è la variabile d’ambiente esterna NODE_ENV che è essenzialmente una variabile d’ambiente dell’utente, mentre environment e apiBaseUrl sono variabili d’ambiente di runtime. Il profilo utente chiamante fornisce il valore della variabile NODE_ENV e l’applicazione lo utilizza per prendere decisioni interne.

Se utilizzate Windows, potreste incontrare delle difficoltà nell’eseguire i due comandi precedenti. Il terminale di Windows potrebbe non permettervi di assegnare al volo le variabili d’ambiente utente utilizzando la sintassi KEY=VALUE (a meno che non si tratti di Bash su Windows).

Una soluzione rapida in questo caso è quella di utilizzare gli script e cross-env.

Installate cross-env eseguendo il seguente comando:

npm i --save-dev cross-env

Successivamente, andate al vostro file package.json e aggiornate la chiave scripts in modo che corrisponda a questa:

// …
"scripts": {
   "test": "echo "Error: no test specified" && exit 1",
   "start-dev": "cross-env NODE_ENV=DEV node index.js",
   "start-staging": "cross-env NODE_ENV=STAGING node index.js"
 },
// …

Ora potete eseguire i seguenti comandi per far funzionare la vostra applicazione con due diversi set di variabili d’ambiente:

npm run start-dev		# to start with dev variables
npm run start-staging		# to start with staging variables

Questa è una soluzione universale e potete utilizzare questi script anche su bash/zsh.

Vediamo ora come utilizzare un variable manager di terze parti.

Tipo 2: Utilizzare lo Strumento di Gestione di Variabili d’Ambiente Nativo di Heroku

Per poter seguire questa parte del tutorial, è necessario avere un account Heroku. Createlo prima di procedere.

Prima di distribuire l’applicazione su Heroku, dovrete apportare alcune modifiche al vostro codice. Prima di tutto, aggiungete un nuovo script nel sito package.json chiamato start:

"scripts": {
   "test": "echo "Error: no test specified" && exit 1",
   "start": "node index.js",
   "start-dev": "cross-env NODE_ENV=DEV node index.js",
   "start-staging": "cross-env NODE_ENV=STAGING node index.js"
 },

Questo script verrà utilizzato da Heroku per eseguire l’applicazione una volta distribuita. Inoltre, andate all’ultima riga del file index.js e aggiornatela come segue:

app.listen(process.env.PORT || 3000);

Questo assicura che l’applicazione venga distribuita sulla porta specificata da Heroku.

Successivamente, sarà necessario installare localmente la CLI Heroku per poter accedere alle vostre app Heroku dalla riga di comando. Per questo tutorial, potete utilizzare il seguente comando per installare la CLI:

npm i -g heroku

Tuttavia, i documenti di Heroku consigliano di installarla tramite uno degli altri modi elencati nel link sopra citato per ottenere un supporto migliore. Una volta installata, eseguite il seguente comando per accedere al vostro account Heroku:

heroku login

Una volta fatto, andate su dashboard.heroku.com e accedete al vostro account. Quindi, create una nuova applicazione cliccando su Nuovo > Crea nuova applicazione.

Creazione di una nuova app.
Creazione di una nuova app.

Nella pagina successiva, cliccate sul pulsante Crea app senza inserire alcun dettaglio. In questo modo verrà creata una nuova app heroku con un nome casuale.

Dare un nome all'app.
Dare un nome all’app.

Ecco come apparirà la dashboard della vostra app:

La dashboard della nuova app.
La dashboard della nuova app.

Questa pagina contiene anche le istruzioni su come distribuire la vostra app su Heroku tramite la CLI. Ecco l’elenco dei comandi che dovrete eseguire per distribuire l’app su Heroku:

git init
heroku git:remote -a whispering-shelf-49396 # change whispering-shelf-49396 with the name of your app. You can get it in your dashboard
git add index.js package-lock.json package.json # do not push the .env files since we'll provide that via the in-app secrets manager git commit -am "Initial commit" git push heroku main 

Una volta che la distribuzione è stata completata con successo, potrete visualizzare l’app distribuita tramite la dashboard cliccando sul pulsante Apri app

Se avete eseguito tutto correttamente, vedrete la seguente risposta:

Accesso all'app distribuita.
Accesso all’app distribuita.

Perché succede questo? Perché non abbiamo ancora fornito le variabili d’ambiente alla nostra applicazione. Se controllate i comandi usati per distribuire l’applicazione, noterete che non abbiamo inviato i file .env al nostro controllo di versione. Inoltre, non abbiamo definito il valore NODE_ENV nello script di avvio.

Per iniettare ora le variabili d’ambiente nell’applicazione, dovrete andare su Impostazioni > Config Vars nella dashboard Heroku. Cliccando su Reveal Config Vars, vedrete una schermata simile:

Accedere alle vars di configurazione dell'applicazione.
Accedere alle vars di configurazione dell’applicazione.

Ora è possibile inserire il contenuto del file .env:

Inserire le variabili di ambiente in Heroku.
Inserire le variabili di ambiente in Heroku.

Tornando indietro e aggiornando l’URL dell’applicazione, noterete che i valori sono stati aggiornati:

L'app distribuita su Heroku può ora accedere alle variabili d'ambiente.
L’app distribuita su Heroku può ora accedere alle variabili d’ambiente.

In questo modo potete utilizzare il gestore dei segreti di una piattaforma di distribuzione per gestire le variabili d’ambiente. Tuttavia, questo richiede che le variabili d’ambiente siano gestite manualmente attraverso la dashboard della piattaforma. Come si può notare, per Heroku non esiste un’opzione per importare un grande dump di variabili d’ambiente da un file, il che costringe l’utente a inserirle una per una. Questo a volte può risultare decisamente scomodo.

La prossima sezione presenta un metodo più efficiente per gestire i segreti delle app: i secret manager.

Tipo 3: Usare Doppler per Gestire le Variabili d’Ambiente

I metodi discussi in precedenza non garantiscono l’uniformità tra le varie piattaforme. Di solito non ci si affida ai file env quando si distribuisce in produzione e non è possibile utilizzare gli strumenti di gestione di variabili nativi della piattaforma quando si lavora in locale. I secret manager come Doppler colmano questa lacuna.

Per provarlo personalmente, dovrete prima creare un account gratuito su Doppler.

Una volta fatto, potrete proseguire. Molto probabilmente Doppler creerà automaticamente un progetto di esempio con il nome di progetto-esempio. Per semplicità, lasciamolo da parte e creiamo un nuovo progetto per il nostro caso d’uso.

Vai alla dashboard e clicca sull’icona più accanto a Progetti.

I vostri progetti in Doppler.
I vostri progetti in Doppler.

Inserite il nome “my-app” e procedete. Ecco come dovrebbe apparire il progetto una volta pronto:

Gli ambienti e le variabili del vostro progetto.
Gli ambienti e le variabili del vostro progetto.

Cliccate sulla voce dell’elenco dev config. Fate clic su Aggiungi nuovo segreto e aggiungete due segreti come segue:

Aggiungere le variabili dev a Doppler.
Aggiungere le variabili dev a Doppler.

Cliccate sul pulsante Salva per salvare le modifiche. Notate che Doppler non supporta il camel casing quando si nominano i segreti. Sebbene sia generalmente preferibile mantenere i nomi dei segreti in maiuscolo, l’utilizzo di Doppler non lascia alternative. Per identificare i segreti che vengono recuperati da Doppler, li abbiamo preceduti da DP_

Ora che le variabili sono state create e memorizzate in Doppler, integriamole nella nostra base di codice. Per farlo, dovete configurare la CLI di Doppler. Ecco un breve riassunto di ciò che dovete fare.

Prima di tutto, installate la CLI in locale seguendo le istruzioni specifiche per il vostro sistema operativo. Successivamente, accedete alla Doppler CLI con l’account appena creato utilizzando il seguente comando:

doppler login

Una volta effettuato l’accesso, esegui il seguente comando per connetterti al progetto Doppler remoto dalla tua CLI:

doppler setup

Una volta collegati al progetto giusto, potrete accedere ai segreti con il seguente comando:

doppler run

Tuttavia, non eseguiremo questo comando direttamente. Lo aggiungeremo invece a uno dei nostri script di esecuzione in modo che venga eseguito automaticamente all’avvio dell’applicazione. Aggiorniamo il file package.json con il nuovo script di esecuzione per l’ambiente dev:

// …
"scripts": {
   "test": "echo "Error: no test specified" && exit 1",
   "start": "node index.js",
   "start-dev": "doppler run -- node index.js", // This has to be updated
   "start-staging": "cross-env NODE_ENV=STAGING node index.js"
 },
// …

Ricordate inoltre che in Doppler abbiamo creato nuovi nomi di variabili che iniziano con DP_. Quindi dovremo aggiornare il nostro file index.js per visualizzare anche questa variabile:

const express = require("express")
require('dotenv').config({
   path: "STAGING" === process.env.NODE_ENV?.toUpperCase() ? './.env.staging' : './.env.dev'
})

console.log(process.env.NODE_ENV)

const app = express()

app.get("/", (req, res) => {
  
   // the responseMessage object extracts its values from environment variables
   // If a value is not found, it instead stores the string "not found"
   const responseMessage = {
       environment: process.env.environment || "Not found",
       apiBaseUrl: process.env.apiBaseUrl || "Not found",
       DP_ENVIRONMENT: process.env.DP_ENVIRONMENT || "Not found" // Add the new variable here
   }

   res.send(responseMessage)
})

app.listen(process.env.PORT || 3000);

Per vedere tutto in azione, eseguite il seguente comando:

npm run start-dev

Ecco come dovrebbe apparire ora http://localhost:3000:

Accesso ai segreti Doppler in un'applicazione in esecuzione locale.
Accesso ai segreti Doppler in un’applicazione in esecuzione locale.

La terza variabile dell’elenco (DP_ENVIRONMENT) viene prelevata direttamente da Doppler.

Quindi, è ora possibile connettere Doppler con la propria piattaforma di distribuzione per accedere a questi segreti tramite l’app distribuita. Per farlo, iniziamo creando un nuovo ambiente in Doppler per un nuovo set di segreti di distribuzione.

Tornate alla pagina iniziale del progetto my-app. Cliccate sull’unica voce dell’elenco Staging:

La dashboard della vostra app.
La dashboard della vostra app.

Noterete che le due variabili segrete che avete definito nell’ambiente dev sono già disponibili qui, ma mancano dei valori:

Le variabili d'ambiente dell'app per l'ambiente di staging.
Le variabili d’ambiente dell’app per l’ambiente di staging.

Aggiungete i seguenti valori e cliccate su Salva:

Le variabili di ambiente dell'app per l'ambiente di staging.
Le variabili di ambiente dell’app per l’ambiente di staging.

Una volta terminato, cliccate sulla scheda Integrazioni e su Aggiungi sincronizzazione in questa pagina per iniziare a connettervi alla vostra piattaforma di distribuzione. Riceverete un elenco di piattaforme con cui Doppler può integrarsi:

Connessione della vostra app Doppler a Heroku.
Connessione della vostra app Doppler a Heroku.

Dato che la nostra app è distribuita su Heroku, facciamo clic su Heroku. Seguite i passaggi sullo schermo per collegare il vostro account Heroku a Doppler e fornire i ruoli di accesso richiesti. Una volta connesso, si aprirà una schermata simile:

Fornire i dettagli della propria app per integrarla con Heroku.
Fornire i dettagli della propria app per integrarla con Heroku.

Selezionate il Tipo di progetto come App, scegliete la vostra app Heroku nell’elenco delle app disponibili, scegliete stg come Config da sincronizzare e Non importare nelle Opzioni di importazione, poiché non vogliamo importare alcun segreto da Heroku a Doppler.

Una volta finito, cliccate su Imposta integrazione. Quando l’integrazione sarà andata a buon fine, si aprirà una schermata simile:

Le integrazioni dell'app Doppler con Heroku.
Le integrazioni dell’app Doppler con Heroku.

Controllando la sezione Config Vars nella dashboard della vostra app Heroku, noterete che le variabili di Doppler sono state aggiunte automaticamente alle config vars della distribuzione Heroku:

I segreti di Doppler sono ora sincronizzati con Heroku.
I segreti di Doppler sono ora sincronizzati con Heroku.

Noterete anche che le due variabili d’ambiente originali (environment e apiBaseUrl) sono state rimosse. Questo è successo perché abbiamo scelto di non importare nelle opzioni di importazione. Se necessario, è possibile aggiungerle di nuovo in Heroku.

Sebbene la presenza delle nuove variabili d’ambiente nella sezione Config Vars di Heroku dimostri che avete configurato Doppler per gestire i segreti sia localmente nell’ambiente di sviluppo sia nell’ambiente di distribuzione, potete procedere con il deployment del codice aggiornato su Heroku per visualizzare le modifiche nell’applicazione distribuita. Ecco come apparirà una volta finito:

Accesso ai segreti Doppler in un'app distribuita su Heroku.
Accesso ai segreti Doppler in un’app distribuita su Heroku.

Questo completa il tutorial per impostare le variabili d’ambiente in un progetto Node.js utilizzando tre metodi molto popolari. Diamo ora un’occhiata ad alcuni modi in cui potete assicurarvi che le variabili d’ambiente e i loro file restino sicuri mentre li si utilizza.

Come Mantenere Sicuri i File delle Variabili d’Ambiente

Sebbene le variabili d’ambiente siano una risorsa utile nelle moderne pratiche DevOps, è necessario essere consapevoli delle implicazioni di sicurezza che possono causare. Ecco alcuni suggerimenti da utilizzare per mantenere i file di variabili d’ambiente sicuri e lontani da occhi indiscreti.

Tenere i File env Fuori dal Controllo di Versione

Una delle cose più importanti da tenere a mente quando si gestisce qualsiasi segreto è di tenerlo lontano dal controllo di versione. Il controllo di versione serve esclusivamente a tracciare le modifiche apportate al codice sorgente della tua applicazione. Tutto ciò che viene inserito in un sistema di controllo delle versioni vi rimane fino a quando non viene cancellato esplicitamente e la maggior parte del vostro team ha accesso a questi dati storici a scopo di riferimento.

Se avete memorizzato le chiavi del vostro bucket di storage AWS o di un servizio API a pagamento in un file env da utilizzare nella vostra applicazione, non vorrete condividerlo con tutto il vostro team di sviluppo a meno che non sia necessario che vi abbiano accesso. Se il vostro progetto è open-sourced su una piattaforma come GitHub, aggiungere file env al vostro VCS potrebbe significare condividerlo con tutto il mondo! I file env sono destinati ad essere memorizzati localmente. È possibile fornire a ogni ambiente di distribuzione i file env pertinenti tramite metodi dedicati.

Aggiungete sempre il file env al vostro file .gitignore (se utilizzate git per il controllo di versione) o utilizzate qualsiasi altro modo per far sì che il vostro VCS ignori i file env durante il commit delle modifiche. Si potrebbe in considerazione l’aggiunta di un file env modello al vostro VCS in modo che qualsiasi altro membro del team possa utilizzarlo come riferimento per creare i propri file env a livello locale.

Controllare il Nome del Pacchetto Prima dell’Installazione

Dato che di solito si installa la maggior parte dei pacchetti da NPM quando si lavora con un’applicazione Node.js, è necessario prestare molta attenzione nel farlo. È risaputo che chiunque può creare e distribuire un pacchetto NPM. Inoltre, non sorprende che le persone commettano spesso degli errori quando digitano il nome di un pacchetto che vogliono installare.

Sono stati riscontrati numerosi casi in cui pacchetti dannosi con nomi simili a quelli di alcuni pacchetti popolari sono stati accidentalmente installati dagli utenti a causa di errori di digitazione. Questi pacchetti sono progettati per accedere alle variabili d’ambiente della vostra applicazione e inviarle via internet ai loro creatori.

L’unico modo per salvarsi è stare attenti quando si installano nuovi pacchetti da internet.

Preferire i Secret Manager ai File env

A causa di problemi come la perdita accidentale durante la condivisione e gli errori di formattazione, i file env non sono certo la migliore opzione disponibile per la gestione dei segreti. Ecco che entrano in gioco i secret manager. I secret manager come Doppler vi permettono di isolare completamente i segreti delle tue app dal codice sorgente e di gestirli in una piattaforma dedicata.

È possibile concedere al proprio team l’accesso a questi segreti direttamente sulla piattaforma e la propria app può accedervi tramite connessioni criptate su internet. Risolve tutti i problemi associati ai file env e permette di mantenere una serie di segreti in base agli ambienti della tua applicazione.

Tuttavia, anche in questo caso ci sono delle avvertenze. I secret manager sono in una fase iniziale del loro sviluppo tecnologico. Inoltre, i secret manager sono piattaforme di terze parti che sono soggette a una serie di problemi di sicurezza. Per questo motivo è importante un’attenta valutazione e selezione del giusto secret manager. Inoltre, se la vostra applicazione, il vostro team di sviluppo o il numero di segreti dell’applicazione non sono tantissimi, i secret manager potrebbero essere una soluzione eccessiva per voi.

Tabella di Riferimento delle Variabili d’Ambiente

Ecco una rapida tabella di riferimento per aiutarvi a familiarizzare con le variabili d’ambiente e il loro utilizzo:

Definizione delle variabili d’ambiente Variabili fornite ai processi dai processi chiamanti
Scopo
  • Memorizzare e proteggere i segreti dell’app
  • Gestire i dati di configurazione specifici dell’ambiente
Tipi Solo per Windows:
  • Sistema
  • Utente
  • Runtime/Processo
Esempi popolari di casi d’uso
  • Chiavi private
  • Nomi di ambiente
  • URL di base delle API, ecc
Come implementarli nella vostra applicazione?
  • file .env
  • Gestori di segreti nativi della piattaforma
  • Servizio di gestione dei segreti dedicato

Riepilogo

Le variabili d’ambiente sono importanti per isolare i dati sensibili dalla vostra applicazione. Aiutano a proteggere i segreti della vostra applicazione e vi permettono di passare facilmente da un set di segreti all’altro a seconda dell’ambiente dell’applicazione. Tuttavia, la loro gestione aggiunge un altro compito alla vostra lista.

Esistono diversi modi per proteggere le variabili d’ambiente, come abbiamo detto sopra. Esplorateli tutti e scoprite quali sono i più adatti a rendere più veloce il vostro progetto.