Qual è il modo preferito per archiviare le configurazioni dell'applicazione?


38

Il più delle volte, conservo la configurazione dell'applicazione di sviluppo nella directory principale del progetto, in questo modo:

app
|-- config.json

Ma questo non sembra essere l'approccio migliore, dal momento che questa configurazione finisce per essere memorizzata nel sistema di controllo della versione, con possibili nomi utente, password e altre cose sensibili trapelate.

12 La guida all'app Factor consiglia di eliminare completamente i file di configurazione e di utilizzare le variabili di ambiente per l'impostazione della configurazione:

... memorizza la configurazione nelle variabili di ambiente. I variatori ambientali sono facili da cambiare tra le distribuzioni senza cambiare alcun codice; a differenza dei file di configurazione, ci sono poche possibilità che vengano controllati accidentalmente nel repository di codice; e a differenza dei file di configurazione personalizzati o di altri meccanismi di configurazione come Proprietà di sistema Java, sono uno standard indipendente dal linguaggio e dal sistema operativo.

Mi sembra davvero carino, ma dove si memorizzano le variabili di ambiente, senza controllarle nel controllo del codice sorgente? E quali strumenti posso usare per passare quelle variabili all'app? Ci possono essere dozzine di opzioni di configurazione e digitarle a mano ogni volta che avvii l'app non è carino, quindi devono essere archiviate in qualche tipo di file da qualche parte. Detto file finirà quindi nel controllo del codice sorgente e torneremo da dove siamo partiti.

Esiste un modo universalmente accettato di gestire le opzioni di configurazione, che non ha il rischio di memorizzare la configurazione locale nel controllo del codice sorgente?


1
Bene, almeno Git ha qualcosa come .gitignoredove posso definire file o cartelle che non dovrebbero essere controllati nel controllo di versione. Come dici tu non vedo dove Env vars dovrebbe davvero aiutare, e hai uno script per impostarli e dovrebbero essere memorizzati insieme al progetto o li hai 'da qualche parte' sul tuo sistema (home directory o anche all'avvio delle macchine) script) che sembra creare molti problemi da solo, specialmente se è necessaria molta configurazione. In ogni caso, dividerei i file di configurazione in modo che le informazioni riservate vadano in file diversi.
Thorsten Müller,

@ thorstenmüller - unico problema con .gitignore che la configurazione di base / template deve ancora essere memorizzata, il che significa che l'app deve leggere due configurazioni: una di base, con opzioni predefinite (memorizzate in scm) e una locale che sostituisce base (e non è memorizzato in scm). Con env vars, immagino che la distribuzione di massa sia più semplice: è più semplice specificare le variabili di ambiente per la nuova configurazione della macchina virtuale piuttosto che scrivere qualcosa in un file non standard.
Rogach,

Bella domanda, dopo che ho iniziato a utilizzare il normale archivio di dati delle applicazioni specifiche dell'utente per questo, la vita è diventata più facile ;-)
Wolf

1
Hai provato "Redis" redis.io . È pensato esclusivamente per l'archiviazione della struttura del valore-chiave.
Karan,

2
@jporcenaluk - Mi piacciono gli archivi di valori-chiave, ma l'aggiunta di un redis completo all'applicazione solo per gestire la gestione della configurazione sembra un po 'eccessiva. D'altra parte, forse non ho mai lavorato su progetti abbastanza grandi.
Rogach,

Risposte:


16

Forse non c'è una buona risposta a questo. Sembra che tu debba archiviare questi dati in un luogo sicuro, poiché un giorno saranno necessari per il ripristino di emergenza. Questo vale anche per i file delle proprietà e gli script che impostano le variabili di ambiente.

  • Con il codice sorgente (in SVN / GIT ecc.) È una pessima idea, poiché questi dati conterranno password del database di produzione e simili.
  • Il backup notturno aziendale può essere sufficiente, ma è improbabile che mantenga una cronologia dei cambiamenti facilmente accessibile.
  • I dati devono essere aggiornati separatamente al software utilizzato. Nel nostro sistema attuale, un cambio di configurazione porta a una nuova generazione di applicazioni, e questo è semplicemente sbagliato.

Attualmente stiamo esaminando le soluzioni a questo problema e ci rivolgiamo a un repository di codice con accesso limitato. Questo repository conterrebbe solo i dati di cofigurazione. Altri hanno esperienze da condividere?


2
Avere due repository separati per un progetto sembra non essere una buona idea: non è possibile eseguire rollback puliti o lavorare con i rami, perché quindi sarà necessario manipolare due repository contemporaneamente (ad esempio, un altro ramo richiede alcune nuove opzioni di configurazione e quando si passare a quel nuovo ramo senza passare anche al repository di configurazione, le cose si rompono in modi strani).
Rogach,

2
@Rogach Prendo il tuo punto. Esistono validi motivi per mantenere una configurazione con il codice, ma come dici nella tua domanda, le cose sensibili devono andare altrove. Quindi due repository sembrano inevitabili. Inoltre, non ho menzionato che i server delle app spesso aiutano qui. Le origini dati e le variabili JNDI possono essere impostate dall'amministratore e non saranno pubbliche.
kiwiron,

Un secondo negozio ha senso. Esistono forse altri tipi di dati, anche confidenziali, che possono essere archiviati insieme alla configurazione (ad esempio i dati di produzione che sono in fase di analisi per risolvere i problemi dei clienti).
Lupo,

1
@Rogach Sembrano attirare un sacco di odio, ma i sottomoduli git gestiranno questo bene, penso - se quello principale fosse impostato correttamente, e il repo ad accesso limitato potrebbe semplicemente vivere al suo interno.
SeldomNeedy,

9

Nell'esaminare i problemi e le possibili soluzioni, mi aiuta a utilizzare un metodo reso popolare da Jeff Atwood : se Dio dovesse creare un modo per archiviare informazioni sensibili sulla configurazione, come lo farebbe?

Bene, avrebbe saputo chi ha bisogno delle informazioni di configurazione e le darebbe solo a quelle persone, e le informazioni non sarebbero mai state accessibili a nessun altro.

La prima parte dovrebbe già essere curata: il sistema di controllo del codice sorgente dovrebbe autenticare gli utenti. E questo approccio ha anche validità secondo il numero 10 dei 10 comandamenti del controllo del codice sorgente di Troy Hunt , "le dipendenze devono essere nel controllo del codice sorgente".

Ma come proteggerlo in caso di perdite? Bene, non ha bisogno di essere memorizzato lì in testo normale! Usa la crittografia. In .NET, esistono dei passaggi che è possibile eseguire per crittografare i dati della stringa di connessione nei file di configurazione . Dovresti trovare i metodi equivalenti per farlo con la tua particolare tecnologia preferita.


3
Volevo solo chiarire: come può essere utile la configurazione della crittografia? A quanto ho capito, ti verrà richiesto di condividere la stessa password di decrittazione tra tutti gli sviluppatori, e questo sembra richiedere problemi.
Rogach,

Se qualcuno al di fuori della tua azienda ottiene l'accesso al tuo repository, le tue password vengono offuscate. Se qualcuno copia i file da un progetto su un'unità USB e li lascia da qualche parte, stessa cosa. Ci vorrà più lavoro da mantenere, ovviamente. Una maggiore sicurezza di solito ha un prezzo conveniente. Questa soluzione è un po 'ingombrante, te lo darò. Sono aperto a un modo migliore per risolvere la domanda del PO!
jporcenaluk,

5

Molte persone criticano l'archiviazione della configurazione in file regolari insieme al codice sorgente, ma nella mia esperienza, questa è in realtà una soluzione abbastanza buona:

  • Semplice da implementare in qualsiasi lingua. In molti, ottieni immediatamente il supporto per file di configurazione complessi. Ad esempio nel caso di Java con Spring Boot, ottieni il supporto YAML che può esprimere qualsiasi struttura ad albero, ed è facile avere file di configurazione separati per ambienti diversi, nonché una configurazione di base da cui i file specifici dell'ambiente possono ereditare.
  • La configurazione è necessaria per eseguire il software e le modifiche al codice spesso richiedono l'aggiunta / modifica delle impostazioni di configurazione, quindi è naturale mantenere insieme configurazione e codice.
  • La memorizzazione della configurazione con l'origine offre tutti i vantaggi del controllo del codice sorgente, come sapere chi ha modificato l'impostazione e quando o essere in grado di controllare le configurazioni durante una revisione periodica del codice.
  • A meno che tu non lavori per la CIA, l'argomento della sicurezza mi sembra esagerato. Pertanto, la password del database viene archiviata in un file sul computer su cui è in esecuzione l'app. Bene, se qualcuno ottiene l'accesso al computer con la tua app, probabilmente sei già nei guai: possono ad esempio rimuovere l'app e avviare la propria app al suo posto sulla stessa porta. In un tale scenario, l'accesso alla password del DB potrebbe non essere un grosso problema. A meno che tutte le connessioni non siano completamente crittografate e abbiano accesso al proprio computer, possono comunque annusare gran parte dei dati interessanti dalle interfacce di rete.
  • Puoi usare uno strumento come Hiera per avere un file di configurazione testuale ma non memorizzare password o altri dati sensibili al suo interno.

Quindi, per molti casi, la configurazione testuale memorizzata nel controllo del codice sorgente insieme al codice è un buon inizio.

Se si utilizza sistemi distribuiti o si desidera essere in grado di sostituire a caldo la propria configurazione senza ridistribuire le applicazioni, è possibile trovare una soluzione basata su un server di configurazione migliore. Spring Cloud supporta tali meccanismi e le configurazioni di back-end possono essere un repository git o Eureka . Puoi anche tirare il tuo usando ad es . Zookeeper . Ognuno di questi approcci renderà più semplice la gestione di configurazioni coerenti su molti server per aggiornare le configurazioni senza dover ricostruire e ridistribuire il software. Questo ha ovviamente un costo, che sta imparando il server di configurazione e come usarlo dalle tue applicazioni, nonché da un altro sistema da distribuire e gestire.


Ma il codice cambia le mani a qualcuno che non possiede i segreti nei file di configurazione, ci sarà un vero casino.
Tim Ludwinski il

@TimLudwinski Le chiavi / i segreti appartengono alla società, non ai singoli sviluppatori, quindi dovrebbero essere mantenuti in modo tale da non perdersi se un singolo individuo se ne va. Potrebbero essere problemi e gestiti da amministratori / team di sicurezza, ad esempio, in modo che esista un registro centrale.
Michał Kosmulski,

5

Stiamo combattendo lo stesso problema in cui lavoro. In questo momento tutte le nostre configurazioni sono basate su file e controllate dal codice sorgente con le singole applicazioni che le utilizzano. Ciò porta alla duplicazione e agli sviluppatori che hanno accesso alle password di produzione / qa anziché solo allo sviluppo.

Detto questo, penso che abbiamo trovato una buona soluzione per il futuro. Stiamo spostando i nostri file di configurazione in un repository git separato (etichettato il repository di configurazione). Abbiamo quindi impostato un server spring-cloud-config (java) che serve semplicemente i file dal repository di configurazione in base ai profili passati ad esso. Questo è ottimo per le applicazioni Java che possono utilizzare il client e scaricarle all'avvio. Per le nostre app PHP / non java elimineremo direttamente il file. (Non ideale). In futuro potremmo scrivere qualcosa che consenta all'applicazione PHP di scaricare da sola le configurazioni e memorizzarle nella cache da qualche parte, ma non è una priorità per la prima esecuzione. Penso a questa soluzione come a una configurazione come servizio che non viola esplicitamente i consigli sulle app a 12 fattori.

Credo che zookeeper possa essere usato per la stessa cosa (ho visto una configurazione con kubernetes + zookeeper), quindi non sono sicuro del perché quella risposta abbia ottenuto un -1 sopra.

link:

https://spring.io/guides/gs/centralized-configuration/

https://cloud.spring.io/spring-cloud-config/


3

Invece di archiviare l'intera configurazione in un file, archiviarlo in più file.

  • Avere una directory di configurazione . Tutti i file lì vengono interpretati come file di configurazione, tranne forse README*.
  • Tutti i nomi dei file sono ordinati alfabeticamente e i file vengono caricati in questo ordine. Questo è il motivo per cui i file in questi casi spesso iniziano con una cifra o due: 01-logging.json. 02-database.json, eccetera.
  • I dati di tutti i file vengono caricati nella stessa struttura di configurazione disponibile per l'applicazione. Questo è il modo in cui diversi file possono integrare le impostazioni degli altri e persino sovrascriverli in modo prevedibile.
  • Memorizzare nel VCS solo i file di configurazione con valori sicuri o valori predefiniti. Aggiungi i file di configurazione con i segreti durante la distribuzione o, ancora meglio, usa un servizio di archiviazione dei segreti autenticato.

Sul tuo Linux box più vicino, dai un'occhiata a /etc/sudoers.do /etc/nginx/conf.d. Mostra lo stesso modello.

La gestione dei segreti è una bestia diversa. Puoi gestirli come un passaggio manuale mentre sei piccolo. Puoi usare cose come Zookeeper. È anche possibile controllare i segreti in un VCS in forma crittografata e decrittografarli come fase di distribuzione. Esistono numerose altre opzioni.

(Inoltre, un pezzo di opinione: JSON non è un buon formato di file di configurazione, perché non consente commenti; i commenti sono cruciali. I formati TOML, YAML e persino INI sono migliori nell'uso pratico.)


2

Penso che le tue opzioni siano in qualche modo definite dal sistema operativo su cui stai implementando

Vorrei suggerire, sì, mettere i valori nel controllo del codice sorgente. MA solo le versioni 'dev'. Vuoi che il tuo codice sorgente si compili e funzioni! non includere passaggi segreti extra

Il processo di compilazione e distribuzione dovrebbe quindi scambiare questi valori per ambiente durante la distribuzione. (il polpo ha questo tipo di modello)


0

Apache Zookeeper offre meravigliose opzioni per memorizzare le configurazioni dell'applicazione per i sistemi distribuiti. Le modifiche apportate a Zookeeper possono essere acquisite ed elaborate avendo un curatore o un listener Zookeeper alla fine dell'applicazione.


6
Quali sono le opzioni? Come funziona? Dove li memorizza? Uno è preferito a un altro? Quali sono i vari vantaggi e svantaggi di ciascuna opzione? In che modo interagisce su diversi sistemi operativi?

3
@Gangz - Sarei interessato a una risposta più dettagliata, per favore non scoraggiarti dai voti negativi e migliorare la tua risposta in modo che possa essere di aiuto.
Jay Elston,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.