Vai al contenuto
GitOps

GitOps: governare ambienti e deploy senza rituali oscuri 🧭

GitOps è una di quelle parole che in molti usano come sinonimo elegante di “deploy via Git”. Peccato che non basti committare un file YAML per fare GitOps. Il punto vero è un altro: Git diventa la fonte di verità dichiarativa per ambienti e configurazioni, mentre un controller riconcilia in modo continuo lo stato reale con quello desiderato.

Se vuoi solo una pipeline che fa deploy, parti da CI/CD. Se vuoi che l’ambiente sia descritto, verificabile, revisionabile e riportato automaticamente allo stato atteso, allora sei nel territorio GitOps.

Cos’è GitOps davvero 🤔

In pratica GitOps significa questo:

  • lo stato desiderato dell’ambiente vive in Git
  • ogni modifica passa da commit, review e audit trail
  • un operatore nel cluster o nell’ambiente legge il repository e applica il cambiamento
  • la riconciliazione è continua, non “una volta sola durante il deploy”

La differenza importante rispetto a molte pipeline classiche è che non chiedi alla CI di “spingere” configurazioni in giro. Chiedi invece a un controller di leggere il repository e convergere verso lo stato dichiarato.

Quando ha senso usarlo ✅

GitOps funziona particolarmente bene quando hai:

  • ambienti Kubernetes o comunque piattaforme dichiarative
  • più ambienti da mantenere coerenti
  • bisogno di audit trail chiaro su configurazioni e deploy
  • team che vogliono review e rollback via pull request invece che SSH creativo in produzione
  • necessità di rilevare e correggere il drift infrastrutturale o applicativo

Ha molto meno senso quando:

  • l’ambiente è fortemente manuale o imperativo
  • il team non ha ancora disciplina minima su repository, review e branching
  • la piattaforma target non si presta bene a riconciliazione e stato dichiarato

Flusso operativo tipico 🔄

Il flusso più sano, semplificando, è questo:

    flowchart LR
  A[Commit applicazione] --> B[CI build e test]
  B --> C[Pubblicazione artefatto immutabile]
  C --> D[Aggiornamento manifest o Helm values in Git]
  D --> E[Pull request e review]
  E --> F[Merge su main]
  F --> G[Controller GitOps rileva il delta]
  G --> H[Riconcilia ambiente]
  H --> I[Osservabilità e verifica]
  

Qui la CI produce artefatti, ma non resta proprietaria dello stato runtime. La responsabilità dello stato desiderato passa al repository GitOps e al controller che lo osserva.

Modello di riconciliazione GitOps 🧠

La parte più importante di GitOps non è il commit. È la riconciliazione continua. In altre parole: il sistema non “applica una volta e spera”. Confronta di continuo stato desiderato e stato reale, segnala divergenze e, quando configurato per farlo, corregge da solo.

    stateDiagram-v2
  [*] --> DesiredInGit
  DesiredInGit --> Reconciling: nuovo commit o refresh
  Reconciling --> Healthy: stato reale allineato
  Healthy --> Drifted: modifica manuale / stato divergente
  Drifted --> Reconciling: rilevazione drift
  Reconciling --> Degraded: sync fallita / policy bloccante
  Degraded --> Reconciling: fix e nuovo tentativo
  Healthy --> [*]
  

Questo è il motivo per cui GitOps ha senso soprattutto su piattaforme dichiarative: il controller deve poter osservare, confrontare e convergere senza inventarsi metà della logica a runtime.

Tool e componenti tipici 🛠️

I mattoni più comuni sono questi:

  • Argo CD: molto diffuso in Kubernetes, ottimo per applicazioni, sync policy e visibilità dello stato.
  • Flux CD: approccio solido e modulare, spesso scelto da chi vuole forte integrazione cloud-native.
  • Helm: utile come packaging layer, ma non coincide con GitOps; da solo non basta.
  • Kustomize: ottimo per overlay ambientali senza trasformare i valori in una caccia al tesoro.
  • External Secrets / Vault / SOPS: fondamentali per non infilare segreti in chiaro nel repository come se fosse il 2009.

Una stack minimale, molto comune, è questa:

  • CI che builda e pubblica un artefatto immutabile
  • registry per immagini o pacchetti
  • repository GitOps separato per manifest e valori ambientali
  • controller nel cluster con sync policy, health check e diff visibile
  • osservabilità su sync, drift, rollout e rollback

Best practice che evitano dolore inutile 🧱

1. Separa codice applicativo e configurazione runtime 📦

Mescolare tutto nello stesso repository può funzionare su team piccoli, ma spesso conviene distinguere:

  • repository del codice applicativo
  • repository dei manifest o delle configurazioni di deploy
  • eventualmente repository platform condivisi

L’obiettivo non è fare più repository “per sport”, ma evitare accoppiamenti inutili e chiarire ownership, review e promozione tra ambienti.

2. Promuovi artefatti, non ricostruire 🚚

GitOps non annulla una best practice CI/CD fondamentale: l’artefatto va costruito una volta sola. La promozione tra ambienti dovrebbe cambiare riferimenti, versioni o parametri, non ricompilare tutto come se nulla fosse successo.

3. Gestisci i segreti in modo serio 🔐

GitOps ama Git, ma Git non è un secret manager. Usa strumenti di cifratura o integrazione con vault e limita l’accesso in modo rigoroso. Un repository pieno di credenziali è un esercizio di post-mortem anticipato.

4. Rendi il drift visibile e governato 🧪

Il drift non va solo corretto: va prima rilevato. Se qualcuno cambia una risorsa a mano in produzione, devi saperlo subito. Decidi esplicitamente quando consentire self-healing automatico e quando richiedere intervento umano.

5. Usa policy e guardrail 🚧

GitOps senza policy rischia di essere solo “automazione veloce di errori versionati”. Integra:

  • policy admission
  • validazione dei manifest
  • controlli di sicurezza
  • regole di naming, tagging e limiti di risorse

6. Definisci una strategia chiara per repository e promozione 🗂️

Una delle prime decisioni che invecchia male, se presa in fretta, è la struttura dei repository. Alcuni team usano un mono-repo con overlay ambientali, altri separano applicazione, configurazione e piattaforma. Nessuna delle due scelte è magica: conta soprattutto che sia coerente e governabile.

Domande utili da chiudere subito:

  • chi può modificare i manifest di produzione?
  • la promozione tra ambienti avviene via merge, cherry-pick o aggiornamento automatico di versioni?
  • i valori specifici di ambiente sono pochi e leggibili o stanno già degenerando in folklore YAML?

Se ogni ambiente ha la propria logica speciale, GitOps smette di semplificare e inizia a collezionare eccezioni.

7. Non trasformare GitOps in una discarica di responsabilità 🧯

GitOps è ottimo per descrivere e riconciliare stato desiderato. È pessimo se lo usi per infilare dentro qualsiasi automazione ti passa per la testa. Alcune cose dovrebbero restare fuori dal controller GitOps o essere governate con attenzione:

  • job una tantum distruttivi
  • migrazioni DB non idempotenti
  • provisioning infrastrutturale pesante nello stesso layer applicativo
  • logiche di business mascherate da configurazione

Più il repository GitOps diventa una valigia dove infili tutto, più perdi chiarezza operativa e rollback affidabile.

Relazione con IaC e CI/CD 🔗

GitOps, CI/CD e IaC non sono rivali. Sono livelli diversi dello stesso film:

  • CI/CD costruisce, testa e pubblica artefatti
  • IaC definisce infrastruttura e servizi come codice
  • GitOps usa Git come fonte di verità e riconcilia automaticamente lo stato desiderato

Una combinazione sana è questa: IaC per creare cluster, rete, storage e identity; CI/CD per buildare artefatti; GitOps per governare configurazioni applicative e deploy continui.

Un modo semplice per leggerla è questo:

  • IaC prepara il terreno
  • CI/CD costruisce il pacco
  • GitOps decide quale versione deve vivere in ogni ambiente e ne sorveglia lo stato

Errori comuni da evitare 🚫

Scambiare GitOps per “kubectl apply da pipeline”: se la CI spinge manifest direttamente nel cluster, sei più vicino a una pipeline tradizionale che a GitOps.

Tenere i segreti in chiaro nel repo: pratica comoda, fino al giorno in cui diventa una lezione molto costosa.

Overlay ambientali ingestibili: se ogni ambiente ha 14 eccezioni, non hai un modello dichiarativo. Hai un puzzle ostile.

Sync automatico ovunque e sempre: l’auto-sync è potente, ma va governato. In produzione senza guardrail può trasformare un errore in un incidente molto efficiente.

Nessuna osservabilità sul controller: se non sai perché un sync è fallito o cosa è stato corretto, stai guidando bendato con un dashboard “molto carino”.

In breve 🧾

GitOps funziona bene quando vuoi ambienti descritti in Git, riconciliazione continua, audit trail e rollback disciplinati. Non è una religione e non sostituisce CI/CD o IaC: li completa. Se implementato bene, riduce configurazioni manuali, drift silenzioso e deploy “artigianali” che invecchiano male.

Ultimo aggiornamento il