Security & DevOps

Creare valore per gli sviluppatori con una Internal Developer Platform

In questo articolo raccontiamo come il team DevOps di Buildo aumenti l'autonomia degli sviluppatori rimuovendo le barriere iniziali sui nuovi progetti, mostrando le potenzialità della propria internal developer platform e degli strumenti essenziali che la compongono.

Sandro Taje Sandro Taje
13 giugno 2024 — 7 min

In Buildo iniziamo sempre ogni progetto dalla comprensione dei bisogni di fondo, anche per i progetti interni. Come team DevOps abbiamo deciso di intervenire per migliorare il flusso di lavoro e l’autonomia del nostro team di sviluppo (puoi leggere come è iniziato lo sviluppo della nostra Clustero Developer Platform nell’articolo precedente, “L’anello mancante per semplificare la complessità dei database”). In sintesi, attraverso interviste e sulla base dell’esperienza passata abbiamo individuato le funzionalità chiave di cui uno sviluppatore avrebbe bisogno:

  • Esporre l’app su internet tramite un URL HTTPS
  • Autenticazione per la segregazione degli accessi tramite l’utenza Google di Buildo
  • La possibilità di iniettare secret da 1Password, che usiamo comunemente in Buildo

Oggi gli sviluppatori che vogliono esplorare una nuova tecnologia hanno bisogno del team DevOps per partire. Il nostro obiettivo è rimuovere le barriere che ostacolano la sperimentazione autonoma. Se lasciata senza controllo, questa situazione porta a un’eccessiva proliferazione di ambienti snowflake unici, difficili da gestire e su cui è difficile condividere conoscenza.

In questo articolo parliamo del nostro approccio per abilitare la sperimentazione autonoma senza il supporto del team DevOps e dei dettagli di implementazione delle nostre soluzioni. Vedremo anche come gli sviluppatori possono interfacciarsi con il nostro sistema tramite semplici file YAML, il ruolo di Argo CD e dell’App Operator e i nostri piani futuri per integrare i database senza attriti.

L’interfaccia per gli sviluppatori

Come può quindi uno sviluppatore sperimentare senza generare ambienti snowflake o richiedere il supporto DevOps?

La risposta è semplice: basta aggiungere un file YAML essenziale a un repository, così che ArgoCD possa installare la tua app nel cluster senza attriti.

apiVersion: applications.buildo.io/v1alpha1
kind: App
metadata:
  name: my-app
  namespace: my-app
spec:
  image: my-app-image:v1.2.3

Argo CD, uno strumento di continuous delivery GitOps dichiarativo per Kubernetes, esamina automaticamente i repository di Buildo alla ricerca di un App CR (la Custom Resource definita dall’Operator) e lo installa nel cluster, attivando l’App Operator per l’installazione principale.

Semplice, no? E per ottenere un indirizzo internet senza esporre il proprio lavoro a tutto il mondo? Bastano poche righe in più e l’App Operator se ne occuperà al posto tuo.

apiVersion: applications.buildo.io/v1alpha1
kind: App
metadata:
  name: my-app
  namespace: my-app
spec:
  image: my-app-image:v1.2.3
  env:
    MY_ENV_VAR: wow
  route:
    domain: my-app.buildo.io
    port: 3000
    path: /custom-path
  auth:
    enabled: true
  secretsFrom: 1password-item
  storage:
    - /cache
    - /data

L’App CR in dettaglio

Avrai notato che il kind App non è una risorsa nativa di Kubernetes. Abbiamo esteso le API di Kubernetes con una custom resource definition per permettere a un operator, l’App Operator di Buildo, di convertire questo semplice YAML in più risorse complesse.

L’App Operator è una parte cruciale della nostra architettura. È stato creato usando l’Operator SDK con Helm. Abbiamo definito la Custom Resource Definition come il nostro contratto con gli sviluppatori. Abbiamo scelto Helm come linguaggio di templating perché è molto diffuso e facile da comprendere. Un limite di Helm, però, è che il client controlla contenuto e versione del pacchetto. Con l’approccio Helm Operator è il team DevOps a occuparsi della manutenzione dell’operator: questo significa che gli sviluppatori non devono cambiare la versione del pacchetto quando un componente dell’infrastruttura viene aggiornato. Per maggiori informazioni puoi leggere il nostro articolo precedente su questo tema.

__wf_reserved_inherit

L’App Operator legge il kind App e lo converte in diversi CR e risorse native.

Ingress, Service e Certificate

Nell’Ingress colleghiamo il dominio specificato dall’utente al Service. Il dominio viene associato all’IP del load balancer tramite ExternalDNS. Se lo sviluppatore opta per l’autenticazione, l’operator include le annotazioni necessarie per integrare Ory Oathkeeper. Il Certificate associato - emesso dall’operator cert-manager tramite Let’s Encrypt - viene generato automaticamente.

...
spec:
  route:
    domain: my-app.buildo.io
    port: 3000
    path: /custom-path
  auth:
    enabled: true
 ...

Ory Oathkeeper autorizza le richieste HTTP in ingresso. Può funzionare come Policy Enforcement Point all’interno della tua architettura cloud, facendo da reverse proxy per l’API o il web server upstream, rifiutando le richieste non autorizzate e inoltrando quelle autorizzate.

ExternalSecret

ExternalSecret è fondamentale per generare un Secret a partire da un elemento di 1Password, che viene poi associato come variabile d’ambiente nel Deployment. L’operator di ExternalSecret e 1Password Secrets Automation rendono possibile questo processo.

...
spec:
  secretsFrom: 1password-item
...

External Secrets Operator è un operator Kubernetes che integra sistemi esterni di gestione dei secret come AWS Secrets Manager, HashiCorp Vault, Google Secrets Manager, Azure Key Vault, IBM Cloud Secrets Manager, CyberArk Conjur e altri. L’operator recupera le informazioni dalle API esterne e le inietta automaticamente in un Kubernetes Secret.

PersistentVolumeClaim

Il PersistentVolumeClaim (PVC) fornisce un volume che viene montato automaticamente sul nostro Deployment. Il PVC crea un PersistenceVolume usando la storage class predefinita di clustero: EBS tramite aws-ebs-csi-driver.

...
spec:
  storage:
    - /var/lib/cache
    - /data
...

Il nostro primo case study: Conto e l’evoluzione della nostra Developer Platform

Non abbiamo dovuto attendere molto per la prima occasione di mettere alla prova il nostro lavoro: Conto, uno dei nostri strumenti interni, aveva bisogno di qualcosa come la nostra piattaforma per migliorare il proprio flusso di lavoro. Essendo uno strumento interno senza un budget dedicato, era piuttosto semplice: una web app Python con Streamlit. Dopo un po’ di tempo, insieme al team di Conto, ci siamo accorti che usavano un volume per mettere in cache alcuni dati e non volevano perderli ogni volta che l’app veniva riavviata per un aggiornamento. Abbiamo visto l’opportunità di migliorare la nostra Clustero Developer Platform risolvendo il problema di Conto, e abbiamo quindi ampliato le funzionalità della piattaforma aggiungendo la possibilità di rendere persistenti i volumi, così che i dati non andassero perduti durante i riavvii dell’app.

Questa storia di successo ha avuto rapidamente eco negli altri team interni, portando all’adozione della nuova funzionalità di Clustero in diversi piccoli progetti. Quella che era nata come una semplice intuizione si è evoluta in una feature che ha reso più autonomi più team, riducendo la dipendenza dal supporto DevOps.

Sviluppi futuri

Siamo riusciti a eliminare gli ambienti snowflake in favore di applicazioni distribuite rapidamente. Il nostro percorso, però, non finisce qui: vogliamo integrare la nostra soluzione anche nei progetti già esistenti. Per farlo ci serve una nuova funzionalità cruciale: i database. Come forse hai letto nell’articolo di Benedetto, in Clustero forniamo già un metodo semplice e dichiarativo per gestire un database, e integreremo questa funzionalità nell’App CR.

Sandro Taje
Sandro Taje DevOps and AI Platform

I moved from full-stack engineering to DevOps. I'm passionate about using Vim and k9s in the terminal and have diverse experience in software development and optimizing DevOps processes.

NEWSLETTER

Ehi, c'è anche una Newslettero!
Sì, proprio con la o.

Ogni mese scegliamo articoli utili ma anche idee fresche e stimolanti. Proprio quello che vorremmo trovare noi in una newsletter!