Architecture as Code: definisci il design del tuo sistema in modo programmatico
C'e' un pattern nell'ingegneria del software che si ripete ogni pochi anni. Una pratica che era manuale e visuale viene codificata, versionata e automatizzata -- e tutto migliora.
E' successo con l'infrastruttura. Siamo passati dal cliccare nelle console cloud allo scrivere file Terraform. E' successo con la configurazione. Siamo passati dall'editare file di config sui server al dichiarare lo stato desiderato nei manifesti Kubernetes. E' successo con gli schema dei database. Siamo passati dall'eseguire script SQL a mano allo scrivere file di migrazione.
Ora sta succedendo con la documentazione dell'architettura. L'architecture as code e' la pratica di definire il design del sistema in modo programmatico -- in file di testo strutturati che possono essere versionati, revisionati, testati e deployati attraverso le stesse pipeline del codice applicativo.
Questa guida copre tutto cio' che serve sapere sull'architecture as code: cos'e', perche' conta, come si confronta con gli approcci solo visuali e come implementarlo in pratica.
Cos'e' l'Architecture as Code?
L'architecture as code (AaC) e' la pratica di definire l'architettura software in file di testo leggibili dalle macchine e scrivibili dagli umani. Invece di disegnare riquadri e frecce in uno strumento visuale, si descrivono i sistemi, i container, i componenti e le loro relazioni in un formato strutturato come YAML, JSON o un DSL dedicato.
Ecco un semplice esempio di architettura definita in YAML:
version: "1.0"
project:
name: "Payment Platform"
description: "Handles all payment processing for the organization"
systems:
- name: Payment Platform
type: software_system
description: "Core payment processing system"
containers:
- name: Payment API
type: api
description: "REST API for payment operations"
technologies: [Go, gRPC, OpenAPI]
- name: Payment Processor
type: service
description: "Processes payment transactions"
technologies: [Go]
- name: Transaction Database
type: database
description: "Stores transaction records"
technologies: [PostgreSQL]
- name: Payment Queue
type: queue
description: "Async payment processing queue"
technologies: [Kafka]
- name: Stripe
type: external_system
description: "Third-party payment gateway"
relationships:
- from: Payment API
to: Payment Processor
label: "Forwards payment requests"
type: uses
- from: Payment Processor
to: Transaction Database
label: "Persists transactions"
type: writes_to
- from: Payment Processor
to: Payment Queue
label: "Publishes payment events"
type: publishes_to
- from: Payment Processor
to: Stripe
label: "Charges cards via"
type: uses
Questo file e' la fonte di verita' completa per l'architettura. Uno strumento come Archyl lo legge, costruisce il modello C4, renderizza diagrammi interattivi e mantiene tutto sincronizzato. Il file vive nel repository Git, proprio accanto al codice che descrive.
Perche' gli approcci solo visuali non bastano
Prima dell'architecture as code, i team tipicamente documentavano la propria architettura usando strumenti visuali -- Lucidchart, draw.io, Miro o Figma. Questi strumenti sono eccellenti per il brainstorming e le sessioni di design iniziali, ma hanno limitazioni fondamentali come documentazione a lungo termine:
Nessun version control
I diagrammi visuali vengono salvati come file binari o proprietari che non possono essere confrontati in modo significativo con un diff. Quando qualcuno modifica un diagramma, si puo' vedere che e' cambiato, ma non si puo' vedere cosa e' cambiato. Non esiste l'equivalente di git diff per un file draw.io. Non si puo' revisionare una modifica a un diagramma in una pull request come si revisiona una modifica al codice.
Con l'architecture as code, ogni modifica e' un diff di testo. Aggiungere un nuovo servizio sono poche righe di YAML. Rinominare un componente e' una modifica su una singola riga. I revisori possono vedere esattamente cosa e' cambiato, perche' e' cambiato (dal messaggio di commit), e approvare o richiedere modifiche.
Nessuna automazione
I diagrammi visuali esistono in isolamento. Non possono innescare azioni, validare regole o integrarsi con pipeline CI/CD. Se il diagramma dice che si hanno 10 servizi ma il cluster Kubernetes ne esegue 12, niente rileva la discrepanza.
L'architecture as code abilita l'automazione. Si possono scrivere regole di validazione che verificano la definizione dell'architettura rispetto all'infrastruttura reale. Si puo' generare documentazione dal file dell'architettura. Si possono innescare alert quando il file dell'architettura diverge dalla realta'.
Nessuna collaborazione a scala
Quando due persone modificano lo stesso diagramma visuale simultaneamente, i conflitti vengono generalmente risolti con le modifiche di una persona che sovrascrivono quelle dell'altra. Non esiste una strategia di merge per i file visuali.
Con l'architecture as code, si applicano i workflow standard di merge Git. Due team possono modificare parti diverse del file dell'architettura e Git le unisce senza problemi. Quando si verificano conflitti, vengono risolti nello stesso modo dei conflitti nel codice -- attraverso la discussione e la risoluzione intenzionale.
Nessuna garanzia di coerenza
Un diagramma visuale puo' contenere qualsiasi cosa. I riquadri possono essere etichettati in modo incoerente. Le frecce possono significare cose diverse in parti diverse dello stesso diagramma. Non c'e' schema, nessuna validazione, nessuna applicazione delle convenzioni di denominazione.
I file architecture as code hanno uno schema. Lo strumento valida il file a ogni modifica. Se si fa riferimento a un container che non esiste, la validazione lo cattura. Se si usa un tipo di relazione non valido, viene segnalato prima che la modifica venga mergiata.
Lock-in e portabilita'
I diagrammi visuali sono spesso legati allo strumento che li ha creati. Passare da Lucidchart a draw.io significa ricreare manualmente ogni diagramma. Passare da uno strumento architecture as code a un altro e' una conversione di formato -- automatizzata e ripetibile.
I vantaggi dell'Architecture as Code
Singola fonte di verita'
Quando l'architettura e' definita in un singolo file (o un insieme di file), c'e' esattamente un posto dove cercare. Non ci sono dubbi su quale diagramma sia attuale, quale pagina Confluence abbia l'ultima versione, o se il PDF che qualcuno ha inviato per email il mese scorso sia ancora accurato.
Code review per le modifiche architetturali
Questo e' forse il vantaggio piu' trasformativo. Quando le modifiche architetturali passano attraverso pull request, ricevono lo stesso scrutinio delle modifiche al codice. Un architetto senior puo' revisionare una proposta di suddivisione di servizi prima che avvenga. Il team puo' discutere le implicazioni di una nuova dipendenza prima che venga introdotta.
+ - name: Notification Service
+ type: service
+ description: "Handles email, SMS, and push notifications"
+ technologies: [Python, Celery, Redis]
+
+ - from: Order Service
+ to: Notification Service
+ label: "Triggers order notifications"
+ type: uses
Questo diff racconta una storia chiara: qualcuno sta aggiungendo un Notification Service e lo sta collegando all'Order Service. I revisori possono fare domande, suggerire tecnologie alternative o proporre confini di servizio diversi -- tutto prima che venga scritta una singola riga di codice applicativo.
La cronologia Git e' la cronologia dell'architettura
Ogni commit al file dell'architettura crea un record permanente di come l'architettura si e' evoluta. Si possono rispondere a domande come:
- Quando e' stato aggiunto il Search Service?
- Chi ha approvato la migrazione da MySQL a PostgreSQL?
- Come appariva l'architettura sei mesi fa?
- Come e' cresciuto il numero di servizi nel tempo?
Questa cronologia e' inestimabile per comprendere l'evoluzione del sistema e per l'onboarding dei nuovi membri del team.
Integrazione CI/CD
L'architecture as code si integra naturalmente nelle pipeline di integrazione e deployment continui. A ogni pull request, si puo':
- Validare il file dell'architettura rispetto al suo schema
- Verificare le regole di conformita' (ad esempio, ogni servizio deve avere un proprietario documentato)
- Generare diagrammi aggiornati
- Rilevare la deriva tra l'architettura documentata e il sistema in esecuzione
- Pubblicare l'architettura sulla piattaforma di documentazione
Questo rende la documentazione dell'architettura un artefatto vivo piuttosto che un documento statico che decade.
Refactoring e automazione
Poiche' le definizioni dell'architettura sono dati strutturati, si possono scrivere script per manipolarle. Serve rinominare un servizio in tutte le relazioni? Un semplice trova-e-sostituisci in un file YAML. Serve generare un report di tutti i servizi che usano PostgreSQL? Si analizza il YAML e si filtra per tecnologia. Serve applicare una convenzione di denominazione? Si scrive un linter.
Formati e DSL per l'Architecture as Code
Esistono diversi formati e DSL per definire l'architecture as code. Ecco una panoramica degli approcci piu' comuni.
Structurizr DSL
Creato da Simon Brown (il creatore del modello C4), Structurizr DSL e' uno dei primi formati architecture-as-code. Usa una sintassi DSL personalizzata:
workspace {
model {
user = person "User"
softwareSystem = softwareSystem "My Software System" {
webapp = container "Web Application" "Delivers content" "Java"
database = container "Database" "Stores data" "PostgreSQL"
}
user -> webapp "Uses"
webapp -> database "Reads from and writes to"
}
views {
systemContext softwareSystem {
include *
autolayout lr
}
}
}
Structurizr ha aperto la strada al concetto di architecture as code per i modelli C4. Tuttavia, la sua sintassi DSL personalizzata ha una curva di apprendimento, e richiede strumenti specifici di Structurizr per il rendering.
Approcci basati su YAML
YAML e' diventato lo standard de facto per la configurazione dichiarativa nel DevOps (Kubernetes, Docker Compose, GitHub Actions, a parte Terraform HCL). Usare YAML per le definizioni dell'architettura ha il vantaggio della familiarita' -- la maggior parte degli sviluppatori sa gia' leggere e scrivere YAML.
Il formato archyl.yaml di Archyl adotta questo approccio:
version: "1.0"
systems:
- name: E-Commerce Platform
type: software_system
containers:
- name: Web Frontend
type: webapp
technologies: [React, TypeScript, Next.js]
- name: API Service
type: api
technologies: [Go, gRPC]
components:
- name: Auth Handler
type: handler
technologies: [JWT, OAuth2]
- name: Product Handler
type: handler
technologies: [REST]
- name: Product Database
type: database
technologies: [PostgreSQL]
relationships:
- from: Web Frontend
to: API Service
label: "Makes API calls to"
- from: API Service
to: Product Database
label: "Reads/writes product data"
L'annidamento rispecchia direttamente la gerarchia C4: i sistemi contengono container, i container contengono componenti. Le relazioni usano nomi leggibili con notazione a punti per la disambiguazione. Il formato e' cercabile con grep, diffabile, e non richiede strumenti specializzati per la lettura.
JSON e altri formati
Alcuni strumenti usano JSON, TOML o altri formati strutturati. Il formato specifico conta meno dei principi: la definizione dell'architettura deve essere basata su testo, versionabile e analizzabile dalle macchine.
Implementare l'Architecture as Code: un workflow pratico
Ecco un workflow passo dopo passo per adottare l'architecture as code nel proprio team.
Passo 1: Iniziare con cio' che esiste
Non cercare di documentare l'intera architettura dal primo giorno. Iniziare con il diagramma dei Container -- il panorama dei servizi. Elencare ogni servizio deployabile, il suo stack tecnologico e le relazioni chiave tra servizi.
Se si usa Archyl, si puo' creare il modello visualmente nella UI e poi esportarlo come archyl.yaml, oppure scrivere il file YAML da zero. Entrambi i percorsi portano allo stesso risultato.
Passo 2: Committare nel repository
Posizionare il file dell'architettura alla radice del repository principale (o in un repository dedicato all'architettura se la codebase e' suddivisa in molti repo). La posizione conta meno del principio: il file deve vivere in Git e passare attraverso la code review.
my-platform/
archyl.yaml # Definizione dell'architettura
src/
docker-compose.yml
.github/
workflows/
architecture.yml # Pipeline CI per l'architettura
Passo 3: Configurare la sincronizzazione CI/CD
Configurare la pipeline CI/CD per sincronizzare il file dell'architettura con Archyl a ogni merge nel branch principale. Questo assicura che i diagrammi visuali e la documentazione interattiva in Archyl riflettano sempre l'ultima architettura committata.
Un workflow GitHub Actions potrebbe apparire cosi':
name: Sync Architecture
on:
push:
branches: [main]
paths: [archyl.yaml]
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Sync to Archyl
run: |
curl -X POST https://api.archyl.com/v1/sync \
-H "Authorization: Bearer ${{ secrets.ARCHYL_TOKEN }}" \
-H "Content-Type: application/yaml" \
--data-binary @archyl.yaml
Passo 4: Effettuare le modifiche architetturali attraverso pull request
Da questo punto in avanti, le modifiche architetturali seguono lo stesso workflow delle modifiche al codice:
- Creare un branch
- Modificare il file
archyl.yaml - Aprire una pull request
- Farla revisionare dal team
- Mergiare nel main
- La CI/CD sincronizza la modifica su Archyl
Questo da' alle modifiche architetturali la stessa visibilita', responsabilita' e tracciabilita' delle modifiche al codice.
Passo 5: Aggiungere regole di conformita'
Man mano che la pratica di architecture as code matura, aggiungere regole di conformita' che validano automaticamente la definizione dell'architettura. Esempi:
- Ogni container deve avere almeno una tecnologia specificata
- Ogni sistema esterno deve avere una descrizione
- Nessun container orfano (ogni container deve avere almeno una relazione)
- Le convenzioni di denominazione sono rispettate (ad esempio, i servizi terminano con "Service")
Il motore di regole di conformita' di Archyl puo' valutare queste regole automaticamente e riportare le violazioni nella pipeline CI o nella dashboard di Archyl.
Passo 6: Far evolvere la definizione nel tempo
Iniziare con sistemi e container. Aggiungere componenti quando servizi specifici diventano abbastanza complessi da giustificare la documentazione interna. Aggiungere ADR quando si prendono decisioni architetturali importanti. Aggiungere contratti API quando si formalizzano i confini dei servizi.
Il file dell'architettura cresce organicamente con il sistema. Non c'e' bisogno di caricare in anticipo ogni dettaglio.
Architecture as Code vs. Infrastructure as Code
L'architecture as code e l'infrastructure as code (IaC) sono pratiche complementari ma distinte.
L'infrastructure as code (Terraform, Pulumi, CloudFormation) definisce cosa deployare e come configurarlo. E' operativo: provisiona server, configura reti e gestisce risorse cloud.
L'architecture as code definisce come appare il sistema e come le sue parti si relazionano. E' descrittivo: documenta la struttura concettuale, le scelte tecnologiche e i confini dei servizi.
La configurazione ideale combina entrambi:
- I file Terraform definiscono l'infrastruttura
- Il file
archyl.yamldefinisce l'architettura - Le regole di conformita' verificano che i due restino allineati
Quando il Terraform aggiunge un nuovo servizio ma il file dell'architettura non lo menziona, il rilevamento della deriva cattura la discrepanza.
Architecture as Code con assistenti AI
Uno dei vantaggi piu' interessanti dell'architecture as code e' che gli assistenti AI possono leggerlo e ragionarci sopra. Quando l'architettura e' definita in testo strutturato, strumenti come Claude Code e Cursor possono:
- Rispondere a domande sull'architettura interrogando il file YAML
- Suggerire modifiche architetturali basate sullo stato attuale
- Generare codice che rispetta l'architettura documentata (ad esempio, usando il database giusto per il servizio giusto)
- Rilevare incoerenze tra il codice e la definizione dell'architettura
Archyl porta questo oltre con il suo server MCP. Gli assistenti AI non leggono solo il file dell'architettura -- possono interrogare il modello architetturale attivo, navigare le relazioni e persino proporre modifiche. L'architettura diventa una sorgente dati programmabile e interrogabile piuttosto che un documento statico.
Errori comuni
Sovra-ingegnerizzare il formato
Non progettare un DSL personalizzato quando YAML o un formato esistente funziona. L'obiettivo e' l'adozione, e l'adozione e' piu' facile quando il formato e' familiare. La maggior parte degli sviluppatori conosce gia' YAML da Docker Compose, Kubernetes e configurazioni CI/CD.
Cercare di catturare tutto
L'architecture as code dovrebbe catturare gli aspetti strutturali del sistema: cosa esiste, come le cose si collegano e quali tecnologie vengono usate. Non cercare di incorporare dettagli operativi (come le policy di scaling), configurazioni runtime (come le variabili d'ambiente) o specifiche comportamentali (come i formati delle risposte API) nel file dell'architettura.
Non applicare il workflow
L'architecture as code funziona solo se le modifiche passano attraverso il workflow definito. Se le persone bypassano il file dell'architettura e fanno modifiche direttamente nello strumento visuale, il file diventa obsoleto. Stabilire convenzioni chiare su quale direzione fa fede.
Ignorare l'output visuale
L'architecture as code non e' un sostituto per i diagrammi visuali -- e' un modo migliore per produrli. Il file di testo e' la fonte di verita', ma i diagrammi renderizzati sono cio' che le persone guardano effettivamente ogni giorno. Assicurarsi che l'output visuale sia accessibile, aggiornato e facile da navigare.
Per iniziare con Archyl
Archyl e' progettato fin dalle fondamenta per supportare l'architecture as code. La piattaforma fornisce:
- DSL basato su YAML che copre l'intero modello C4 con sistemi, container, componenti, relazioni e tecnologie
- Sincronizzazione bidirezionale -- modellare visualmente nella UI ed esportare in YAML, o scrivere YAML e sincronizzare nella UI
- Integrazione CI/CD per la sincronizzazione automatica a ogni commit
- Regole di conformita' che validano la definizione dell'architettura rispetto ai propri standard
- Server MCP che rende l'architettura interrogabile dagli assistenti AI
- Funzionalita' di collaborazione con code review, commenti e proprieta' del team
Che si stia partendo da zero o migrando da diagrammi visuali, Archyl rende l'architecture as code pratico per team di qualsiasi dimensione.
Inizia con l'architecture as code e porta lo stesso rigore alla documentazione dell'architettura che gia' si porta all'infrastruttura e al codice applicativo.