Come strutturare il codice e le configurazioni correlate a DevOps in un repository di codice?


10

Stiamo crescendo come azienda, i nostri prodotti si stanno espandendo e anche le attività e gli sforzi relativi a DevOps stanno crescendo: siamo passati da Bamboo a Jenkins più flessibile e configurabile, utilizzando pipeline di distribuzione e altri plug-in; passato ad Ansible e iniziando a usare Docker qua e là internamente.

Tutte queste cose richiedono un certo livello di codifica o configurazione: script e configurazioni configurabili, script groovy di Jenkins, file Docker e configurazioni YAML.

Per adesso, abbiamo creato un separato "ops" repository con le directory di alto livello per jenkins, ansible, dockere other(che è un nome terribile, ma per il momento tutte le cose "altre" DevOps automazione ci sono).

Il nostro approccio non sembra corretto e potrebbe non essere scalabile, ma quali sono le migliori pratiche e raccomandazioni per mantenere il codice relativo a DevOps in un repository o repository di codice?


6
Vado con il metodo "ogni parte è un'app, un repo per app", in chef significa 1 repo per libro di cucina.
Tensibai,

@Tensibai, avevo paura che un singolo repository "ops" sarebbe diventato presto poco pratico. Grazie.
Alecxe,

1
Questa è stata la forma legacy di gestione del libro di cucina in uno chef, 1 repository con tutto il libro di cucina e nella maggior parte dei casi ha dimostrato di essere una pistola. i file docker dovrebbero vivere con il progetto che gestiscono l'IMO, e non ho idea di cosa metti sotto gli altri, quindi non posso davvero dare alcun consiglio qui
Tensibai

@Tensibai capito! Altro è costituito principalmente da utility bash e python o script eseguiti periodicamente per più strumenti interni..non si adattano davvero da nessuna parte e non potremmo pensare a un posto migliore di "altro" .. Vedrò se posso pubblicare i contenuti delle directory anche nella domanda. Grazie.
Alecxe,

1
Li dividerei in repository multipli per "affinità" di lavoro, script che lavorano insieme sull'app X, potresti avere uno script usato su due app, ma se app Un cambiamento nel modo in cui lo script deve gestire con quale app parla , è meglio avere due versioni separate, quindi ATEOTD le memorizzerei con l'applicazione a cui si riferiscono o se si estendono su applicazioni multiple in un repository specifico per attività, quindi hai sempre una versione in linea con le applicazioni distribuite e è necessario taggare uno script non correlato allo stesso tempo.
Tensibai,

Risposte:


4

L'attuale organizzazione del codice e della configurazione che descrivi è strutturata dalle soluzioni tecniche coinvolte. Questo è un cattivo design che aggiungerà molto overhead nelle nostre attività di manutenzione e aggiungerà anche molte trappole sulla nostra strada. Invece, tale organizzazione dovrebbe essere strutturata attorno ai manufatti che stiamo implementando.

La ragione di ciò è che vogliamo considerare i manufatti ( ad esempio un'immagine docker o un pacchetto software) come gli oggetti dei seguenti verbi:

  • costruire
  • test
  • Deploy

considerare una serie minima di attività automatizzate che vogliamo svolgere. Se vogliamo cambiare qualcosa su come viene implementato il verbo di prova, è facile visitare la cartella corrispondente a quel manufatto nel repository appropriato e quindi scoprire gli elementi di automazione specifici di jenkins che devono essere aggiornati. Invece, se le ricette di automazione sono strutturate attorno a soluzioni tecniche, allora dobbiamo capire all'improvviso che jenkins è coinvolto nelle procedure di test e trovare lì gli elementi di automazione relativi agli artefatti. In situazioni complesse, l'organizzazione attorno alle soluzioni tecniche rende gli aggiornamenti molto difficili, perché dobbiamo conoscere a priori tutte le soluzioni tecniche coinvolte in alcuni servizi per aggiornarle di conseguenza.

Ad esempio, un repository contenente il codice per un sito Web e un micro-servizio "a" potrebbe avere le seguenti sottodirectory dedicate alle operazioni:

./ops/website
./ops/micro-service-a

ciascuno con tre script chiamato build, teste deploy. Ora che l'organizzazione degli articoli di automazione è stata in qualche modo chiarita, rivolgiamo la nostra attenzione alla configurazione.

Le principali condizioni e requisiti sull'organizzazione della configurazione sono impostate dal deployverbo quando applicate su un artefatto simile a un servizio. Il deployverbo dovrebbe avere i seguenti parametri:

  • la versione del manufatto da distribuire,
  • il target di distribuzione del manufatto, che descrive l'ambiente concreto in cui verrà eseguito il manufatto distribuito ( ad esempio un cluster e gli endpoint con cui dovrebbe parlare)
  • le credenziali che dovrebbe utilizzare per connettersi ad altri endpoint ( ad es. database)
  • la configurazione di runtime di (come la durata delle voci della cache, ecc.)

Dal punto di vista operativo, questa suddivisione della parametrizzazione corrisponde ai naturali gradi di libertà del problema di distribuzione - a parte le credenziali che potrebbero essere raggruppate con la configurazione di runtime, ma è meglio separarle per evitare di diffonderle con noncuranza.


5

Posso rispondere alla finestra mobile, una delle migliori pratiche per utilizzare la finestra mobile è quella di mantenere il file finestra mobile e i file di composizione nello stesso repository del progetto, quindi ovunque si cloni il progetto è possibile creare l'immagine della finestra mobile, ed è bene mantenere ad esempio più versioni della finestra mobile comporre i file (prod, staging, dev) in modo da poter creare l'immagine ed eseguire il contenitore con un'opzione specifica per ogni ambiente, ad esempio per la macchina dev è possibile utilizzare una rete specifica ed eseguire più contenitore di dipendenze o altro.


4

Il codice di ogni strumento va nel proprio repository. per es

  1. Modello di Jenkins Groovy in un repository Jenkins
  2. Ansible playbook YAML nel proprio repository (con ruoli, attività, sottodirectory dell'inventario
  3. Modelli di Cloudformation / Terrform nel proprio repository
  4. File Docker nel suo 5 .. E così via

Ciò ti aiuterebbe a scalare meglio in termini di orchestrazione dei processi e mantenimento di vari rami per ogni ambiente

Ciò ti darebbe un controllo più granulare e scaricherà tutto il tuo overheading di versione sui sistemi di controllo della versione. Crea anche rami separati per ogni ambiente e tagga il codice per ogni versione di produzione (come facciamo per la base di codice dell'applicazione). Pensa a Infra ed elabora in termini di codice. (Qualsiasi modifica al processo deve essere codificata e inviata a QA, SIT, UAT e quindi a PROD) in modo simile all'applicazione.

Ad esempio, potresti avere V2.1 di Ansible in esecuzione in Production (ramo principale) ma V2.0 di container docker in esecuzione in Prod (ramo principale)

Allo stesso modo mantieni i tuoi script DB / script bash nei loro repository e forse puoi avere un file healthcheck (JSON / YAML) configurato per mostrare le versioni di tutti gli strumenti / parti in ciascun URL distribuito per scopi di tracciamento e automazione. (In modo che i tuoi webhook leggano l'URL e automatizzino le distribuzioni)


2
La trappola di questo approccio è che la v2.1 è in qa e non convalidata e devi applicare urgentemente una patch alla produzione, non puoi modificare la v2.0 e se crei una v2.2 per questa patch c'è un alto rischio che sia perso o sovrascritto quando v2.1 va in produzione, moltiplicalo per la quantità di codice separato in un repository e presto avrai un incubo di backport (funziona, ma ho dovuto aggiungere questo disclaimer :))
Tensibai

3
Usare le filiali per tenere traccia delle informazioni specifiche sull'ambiente / sulla distribuzione mi sembra un modello di formica: se abbiamo 20 ambienti, ciò significa che abbiamo 20 filiali da mantenere sincronizzate ... una probabile fonte di errori e confusione. Potresti spiegare perché non usi i file di configurazione per tenere traccia delle informazioni specifiche sull'ambiente / sulla distribuzione e come funziona il tuo flusso di lavoro con questi rami? Questi non sono problemi banali!
Michael Le Barbier Grünewald,

3

Fare una distinzione tra Ops, Dev e DevOps promuove l'isolamento e applica una mentalità "buttalo oltre il muro". Per aumentare la cooperazione tra i team si dovrebbe mettere tutto in un repository necessario per costruire e distribuire il progetto.

Detto questo, la risposta alla domanda:

Come strutturare il codice e le configurazioni correlate a DevOps in un repository di codice?

è che se è richiesta la configurazione per eseguire il progetto, allora si dovrebbe inserirlo nella stessa directory.

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.