Una delle sfide più frustranti nello sviluppo di applicazioni oggi è la parità d’ambiente. Mentre gli anni recenti hanno dimostrato che gli strumenti di virtualizzazione e containerizzazione come Vagrant e Docker (e lo stesso State Tool di ActiveState) possono assicurare che i sistemi operativi e le dipendenze che alimentano l’infrastruttura di un’applicazione siano coerenti tra gli ambienti, le dipendenze esterne sono quasi impossibili da replicare in un ambiente non di produzione.

In un mondo in cui le dipendenze di terze parti sono diventate irreversibilmente intrecciate con la logica di core business di quasi tutti i progetti software, sta diventando sempre più difficile mantenere gli ambienti di sviluppo, staging e produzione coerenti tra loro. Mentre alcuni prodotti con lookalike self-hosted – come Minio per Amazon S3 – alleviano il dolore della gestione di distribuzioni multiple di un singolo servizio, fanno poco per facilitare la sfida della gestione della configurazione tra gli ambienti.

Quando la produzione, la messa in scena, lo sviluppo, la macchina locale di Bob e l’ambiente QE richiedono tutti una diversa distribuzione di un dato servizio, passare file di configurazione avanti e indietro, o fare affidamento su condizionali complessi per determinare con quale distribuzione un dato ambiente dovrebbe parlare, diventa sempre più impraticabile. La necessità di flessibilità evidenzia anche la difficoltà di queste soluzioni in un ambiente su larga scala. Cosa succede se, per esempio, la macchina locale di Bob ha bisogno di parlare temporaneamente con un servizio che è riservato all’ambiente Staging?

Variabili d’ambiente in Python

La configurazione degli ambienti incrociati è una sofferenza, ma fortunatamente i problemi descritti sopra sono diventati abbastanza comuni negli ultimi anni da essere quasi risolti. Grazie al supporto della comunità open source, e all’evangelizzazione delle best-practice come la 12 Factor Application, c’è stato uno spostamento negli ultimi anni dalla gestione della configurazione delle applicazioni basata su file alla gestione della configurazione basata su variabili d’ambiente.

Disponibili in tutti i principali sistemi operativi, le variabili d’ambiente sono – proprio come il loro nome implica – variabili che sono implementate a livello di ambiente per definire il modo in cui le applicazioni in esecuzione sotto di esso dovrebbero comportarsi. In termini più semplici, sono variabili indipendenti dall’applicazione che sono gestite al di fuori del contesto di un dato processo. Il vantaggio principale nell’uso delle variabili d’ambiente è che questo permette agli sviluppatori di definire come un’applicazione dovrebbe essere eseguita senza cambiare una riga di codice.

Per esempio, se la macchina locale di Bob ha bisogno di parlare al servizio CDN che è riservato all’ambiente Staging, può cambiare la variabile d’ambiente CDN_URL per riflettere ciò che è definito in Staging senza dover toccare alcun codice gestito. Ancora più importante, questo permette a Bob di definire servizi finti o interni da usare con i test unitari e di integrazione, il tutto senza dover scrivere una sola riga di codice extra.

Definire le variabili d’ambiente

Mentre l’atto di definire le variabili d’ambiente è generalmente dipendente dal sistema operativo, la maggior parte dei linguaggi di programmazione ha astratto queste differenze attraverso l’uso di pacchetti di sviluppo come il progetto dotenv di Python. Per esempio, piuttosto che dover definire una variabile d’ambiente API_USER a livello di sistema operativo, un file .env localmente gitignored può mantenere le variabili d’ambiente attraverso gli ambienti di sviluppo. Questo permette agli sviluppatori di utilizzare un file di configurazione gestito localmente per impostare le variabili d’ambiente, mentre allo stesso tempo permette la configurazione tramite variabili d’ambiente “vere” in ambienti non di sviluppo.

Come esempio, ecco un semplice file .env che uno sviluppatore può utilizzare nel suo ambiente locale:

APP_ENVIRONMENT=localAPP_NAME=localhostQUEUE_DRIVER=syncAPI_USER=bob

Dal canto suo, l’ambiente di produzione può definire le sue variabili d’ambiente all’interno di un Dockerfile, entrambi i quali sono metodi validi per mantenere variabili d’ambiente.

Ricerca delle variabili d’ambiente

Indifferentemente da come le variabili d’ambiente sono definite, possono sempre essere recuperate in Python usando il metodo os.getenv():

import os# Get environment variablesUSER = os.getenv('API_USER')

Si noti che, nel caso in cui la variabile d’ambiente sia indefinita, il valore predefinito sarà None.

Iniziare con i segreti

Ora, mentre le variabili d’ambiente sono un’eccellente soluzione per gestire configurazioni disparate tra gli ambienti, non sono una pallottola d’argento. Nell’attuale clima di sviluppo, la sicurezza deve essere una priorità assoluta e i dati sensibili devono essere conservati in modo sicuro.

Purtroppo, le variabili d’ambiente da sole non sono sicure. Mentre fanno un ottimo lavoro per memorizzare i dati di configurazione, il modo in cui definiamo dati più sensibili come password, chiavi API e chiavi di crittografia dovrebbe richiedere più attenzione. È qui che entrano in gioco i segreti. Crittografati a riposo, i segreti dovrebbero essere recuperati solo in un singolo runtime, se necessario, al fine di ridurre le probabilità di una violazione dei dati. In questo modo, anche se il tuo fornitore di hosting viene compromesso, puoi essere certo che i tuoi segreti sensibili siano ben chiusi.

Creazione &Gestione dei segreti con lo strumento di stato

Come facciamo a creare e gestire i segreti? Mentre ci sono diversi modi per affrontare questo problema, lo State Tool di ActiveState è una soluzione eccellente per il linguaggio Python. Simile a virtualenv o pipenv, lo State Tool è un’interfaccia di gestione dell’ambiente virtuale che impedisce la contaminazione incrociata delle installazioni e delle configurazioni Python tra progetti. Ciò che lo distingue dagli altri strumenti di gestione degli ambienti virtuali è la sua integrazione con la piattaforma ActiveState, permettendo un’interfaccia centrale per la gestione delle configurazioni dell’ambiente e, sì, dei segreti.

Prima di poter sfruttare le capacità di gestione dei segreti dello State Tool, dobbiamo prima usare lo State Tool per impostare un ambiente virtuale nella directory del nostro progetto. Per fare questo, prima identificate il progetto ActiveState con cui lavorerete (per questo tutorial, potete usare il mio progetto zachflower/envs-vs-secrets-demo se avete un account gratuito ActiveState Platform, oppure potete crearne uno vostro). Poi, esegui il comando state activate per il tuo progetto dato:

$ state activate zachflower/envs-vs-secrets-demo Where would you like to checkout zachflower/envs-vs-secrets-demo? /home/zach/Projects/miscellaneous/activestate-variables/zachflower/envs-vs-secrets-demoActivating state: zachflower/envs-vs-secrets-demoThe State Tool is currently in beta, we are actively changing and adding features based on developer feedback.Downloading required artifactsDownloading 1 / 1 Installing 0 / 1 0 %You are now in an 'activated state', this will give you a virtual environment to work in that doesn't affect the rest of your system.Your 'activated state' allows you to define scripts, events and constants via the activestate.yaml file at the root of your project directory.To expand your language and/or package selection, or to define client-side encrypted secrets, please visit https://platform.activestate.com/zachflower/envs-vs-secrets-demo.To try out scripts with client-side encrypted secrets we've created a simple script for you in your activestate.yaml, try it out by running 'helloWorld'

Come puoi vedere, il comando activate imposta l’ambiente virtuale come definito nel tuo progetto ActiveState. Nel caso in cui il progetto non sia stato ancora configurato, un progetto semplice sarà seminato con parametri predefiniti per fornirvi un esempio di come tutto dovrebbe andare insieme. Questa configurazione è memorizzata in un file alla radice della directory del tuo progetto chiamato activestate.yaml.

File di configurazione per segreti &più

Il activestate.yaml file definisce un runtime di sviluppo sotto il quale la tua applicazione verrà eseguita. Per esempio, quello predefinito definisce un semplice script che utilizza un segreto, così come alcuni ascoltatori di eventi che eseguono azioni ogni volta che si verifica un evento definito:

project: https://platform.activestate.com/zachflower/envs-vs-secrets-demoscripts:# This script uses a secret. Note that you can define your own secrets at# https://platform.activestate.com/zachflower/envs-vs-secrets-demo/scripts - name: helloWorld value: echo ${secrets.user.world}events: # This is the ACTIVATE event, it will run whenever a new virtual environment is created (eg. by running `state activate`) # On Linux and macOS this will be ran as part of your shell's rc file, so you can use it to set up aliases, functions, environment variables, etc. - name: ACTIVATE constraints: os: macos,linux value: | echo "You are now in an 'activated state', this will give you a virtual environment to work in that doesn't affect the rest of your system." echo "" echo "Your 'activated state' allows you to define scripts, events and constants via the activestate.yaml file at the root of your project directory." echo "" echo "To expand your language and/or package selection, or to define client-side encrypted secrets, please visit https://platform.activestate.com/zachflower/envs-vs-secrets-demo." echo "" echo "To try out scripts with client-side encrypted secrets we've created a simple script for you in your activestate.yaml, try it out by running 'helloWorld'"

Mentre non c’è nulla di particolarmente innovativo qui, il potere potenziale di questo file dovrebbe essere immediatamente ovvio. Per esempio, il seguente script fornisce un esempio di base di come utilizzare i segreti nel file di configurazione:

scripts:# This script uses a secret. Note that you can define your own secrets at# https://platform.activestate.com/zachflower/envs-vs-secrets-demo/scripts - name: helloWorld value: echo ${secrets.user.world}

Quando il comando helloWorld viene eseguito (da uno stato attivato), esso riporterà il valore del segreto user.world e, nel caso in cui il segreto non sia ancora definito, richiederà un valore:

$ helloWorldThe action you are taking uses a secret that has not been given a value yet.Name: worldDescription: - (This secret has no description, you can set one via the web dashboard)Scope: user (Only you can access the value) Please enter a value for secret "world": ******

Using Secrets

Anche se l’esempio è relativamente semplicistico, il vero valore dei segreti viene dagli eventi di attivazione. Invece di recuperare un valore segreto nel contesto di uno script, le variabili d’ambiente possono essere definite utilizzando i segreti recuperati senza mai esporre tali segreti al di fuori di questo ambiente sicuro:

project: https://platform.activestate.com/zachflower/envs-vs-secrets-demo?commitID=5fd1c161-c5a4-480c-8aba-29d8ab361b42events: - name: ACTIVATE constraints: os: macos,linux value: | export WORLD=${secrets.user.world}

Ora, se il segreto user.world è definito, allora la variabile d’ambiente WORLD sarà definita e potrà essere recuperata come qualsiasi altra variabile d’ambiente:

$ echo $WORLDworld!

Tuttavia, se non è definita, allora l’utente sarà invitato a definirla all’attivazione dell’ambiente virtuale ActiveState:

The action you are taking uses a secret that has not been given a value yet.Name: helloDescription: - (This secret has no description, you can set one via the web dashboard)Scope: user (Only you can access the value) Please enter a value for secret "world": ******

Fico, no?

Passando oltre

La gestione della configurazione nello sviluppo di applicazioni è, per la maggior parte, un problema risolto, ma la gestione dei segreti non lo è ancora. Il numero di progetti che hanno controllato i dati sensibili in un repository di controllo della versione è sbalorditivo, ed è qualcosa che anche aziende molto rispettate hanno fatto, ma attraverso l’uso di una corretta igiene di sicurezza e prodotti come State Tool di ActiveState, mantenere i dati di configurazione sensibili sicuri e protetti sta diventando sempre più facile.

  • Provalo tu stesso creando un account gratuito su ActiveState Platform e scaricando State Tool per semplificare la gestione dei segreti.
  • Puoi anche guardare il nostro webinar su come gestire i segreti condivisi utilizzando lo State Tool

Blog correlati:

Il segreto per gestire i segreti condivisi

Gli sviluppatori possono condividere i segreti in modo facile e veloce senza sacrificare la sicurezza

.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.