Architettura senza server Azure Function con i micro servizi
Matteo Migliore

Matteo Migliore è un imprenditore e architetto software con oltre 25 anni di esperienza nello sviluppo di soluzioni basate su .NET e nell'evoluzione di architetture applicative per imprese e organizzazioni di alto profilo.

Ha guidato progetti enterprise, formato centinaia di sviluppatori e aiutato aziende di ogni dimensione a semplificare la complessità trasformando il software in guadagni per il business.

C’è un momento preciso nella vita di un architetto software in cui il concetto di "server" smette di essere una risorsa e inizia a diventare un limite.

Accade quando ti accorgi che il tuo team passa più tempo a configurare, patchare e scalare macchine virtuali che a scrivere logica di business in grado di generare valore.

È quella sensazione sottile ma persistente che l’infrastruttura stia diventando un’ancora anziché un acceleratore.

Azure Func (o Azure Functions) entra in gioco esattamente qui.

Ma attenzione: non è la bacchetta magica che molti venditori di cloud vogliono farti credere.

Se usata male, trasforma un monolite ordinato in un "nanoservizio" distribuito impossibile da tracciare, dove la latenza esplode e i costi diventano imprevedibili.

Il passaggio al serverless non è solo un cambio di tecnologia, è un cambio di paradigma mentale.

Significa smettere di pensare in termini di "macchine che aspettano richieste" e iniziare a ragionare in termini di "eventi che scatenano reazioni".

Tuttavia, c’è un divario enorme tra scrivere una funzione "Hello World" che gira in locale e progettare un sistema serverless resiliente, sicuro e scalabile in produzione.

In questo articolo non ci limiteremo a leggere la documentazione.

Andremo a dissezionare l’architettura dietro Azure Func, analizzando i costi reali, i rischi nascosti come il Cold Start e le strategie di governance che distinguono un junior che "prova" il cloud da un Architetto che lo domina.

Se vuoi costruire sistemi che scalano all'infinito senza far esplodere il budget aziendale, devi capire cosa succede davvero dietro le quinte del serverless.

Che cos'è Azure Func: il tassello fondamentale del serverless

Molti sviluppatori definiscono Azure Func semplicemente come "codice che gira senza server".

Questa definizione è tecnicamente corretta, ma architetturalmente povera.

Dal punto di vista di un Architetto Software, Azure Func è il collante dinamico del cloud.

È un servizio FaaS (Function-as-a-Service) che ti permette di eseguire piccoli pezzi di logica in risposta a eventi, astraendo completamente l'infrastruttura sottostante.

Non devi preoccuparti del sistema operativo, del runtime o del patching: Microsoft si occupa dell'hosting, tu ti occupi solo del codice.

Tuttavia, considerarlo solo un modo per "eseguire script" è riduttivo.

Azure Func è progettato per scalare orizzontalmente in modo quasi istantaneo.

Se arriva una richiesta, il cloud provisiona un'istanza. Se ne arrivano dieci milioni, il cloud provisiona (teoricamente) le risorse necessarie per gestirle in parallelo, per poi distruggerle appena il lavoro è finito.

Questo modello di "compute on-demand" cambia radicalmente l'economia del software.

Non paghi per la capacità prenotata (come in una VM che gira a vuoto di notte), ma paghi per l'esecuzione effettiva: durata e memoria utilizzata.

Ma è qui che molti cadono: senza una governance corretta, la frammentazione della logica in centinaia di piccole funzioni può creare un "distributed monolith" difficile da manutenere.

Capire cos'è veramente Azure Func significa comprendere che non è la soluzione a tutto, ma uno strumento di precisione per gestire carichi imprevedibili e flussi di lavoro asincroni.

Architettura event- driven: perché affiancare al monolite le funzioni

Il monolite ha un grande vantaggio: è semplice. Tutto è lì, in memoria, a una chiamata di funzione di distanza.

Ma ha un difetto fatale: scala tutto insieme o non scala affatto.

Se il modulo di generazione PDF consuma tutta la CPU, rallenta anche il modulo di login, bloccando tutti gli utenti.

L'architettura basata su Azure Func spinge verso un modello Event-Driven.

In questo scenario, i componenti non si "chiamano" direttamente (accoppiamento stretto), ma emettono eventi.

Un file caricato su uno Storage Account è un evento. Un messaggio in una coda Service Bus è un evento. Un record modificato in Cosmos DB è un evento.

Le tue funzioni reagiscono a questi eventi in modo isolato.

Questo porta tre vantaggi strategici enormi per un Architetto:

  • Scalabilità granulare: se il processo di generazione PDF è sotto carico, Azure scalerà solo le funzioni dedicate a quel compito, lasciando il resto del sistema intatto e reattivo.
  • Resilienza: se una funzione fallisce, non trascina giù l'intero sistema. Il messaggio può tornare in coda per essere riprocessato (retry policy) o spostato in una Dead Letter Queue.
  • Velocità di sviluppo: team diversi possono lavorare su funzioni diverse in linguaggi diversi (C#, Python, Node.js) senza pestarsi i piedi, purché il contratto dell'evento sia rispettato.

Abbandonare il monolite richiede coraggio, ma soprattutto richiede competenza nella gestione della complessità distribuita.

Molti sviluppatori si lanciano nel serverless senza capire i pattern di messaggistica, finendo per creare sistemi fragili.

Nel Corso Architetto Software, non insegniamo solo la sintassi, ma come progettare il flusso dei dati affinché il sistema sia robusto anche quando i servizi falliscono.

Gestione operativa: muoversi nel Portal Azure senza perdere il controllo

Il Portal Azure è potente, ma può diventare un labirinto se non hai una strategia di organizzazione chiara.

Quando inizi con una sola Azure Func, tutto sembra facile. Clicchi "Create", scrivi codice nel browser (non farlo mai in produzione!) e vedi il risultato.

Ma quando hai 50 funzioni, 3 ambienti (Dev, Stage, Prod) e risorse collegate come Storage, Key Vault e Application Insights, il caos prende il sopravvento.

La gestione operativa richiede disciplina.

Il primo passo è l'uso rigoroso dei Resource Groups per raggruppare logicamente le risorse che condividono il ciclo di vita.

Il secondo è l'adozione dell'Infrastructure as Code (IaC) tramite Bicep o Terraform.

Un Architetto non configura le funzioni a mano nel portale: definisce l'infrastruttura come codice, rendendola replicabile e auditabile.

Nel Portal Azure, devi imparare a monitorare non solo il codice, ma la "salute" della Function App:

  • Controllare le quote e i limiti del piano di consumo.
  • Gestire le chiavi di accesso (Host Keys) e ruotarle periodicamente.
  • Configurare correttamente le impostazioni dell'applicazione (Environment Variables) senza esporre segreti in chiaro.

Muoversi nel portale senza perdere il controllo significa sapere esattamente dove guardare quando le cose non funzionano, ignorando il rumore di fondo delle mille opzioni non necessarie.

Triggers e Bindings: come connettere i servizi riducendo il codice

Questa è la vera "killer feature" di Azure Func rispetto ad altri concorrenti o soluzioni custom.

In un'applicazione tradizionale, se vuoi leggere un messaggio da una coda, devi: istanziare il client, gestire l'autenticazione, aprire la connessione, fare polling, gestire le eccezioni di rete, deserializzare il messaggio e infine chiudere la connessione.

È tutto codice "boilerplate": noioso, ripetitivo e propenso all'errore.

Azure Func risolve questo problema con Triggers e Bindings.

Il Trigger è ciò che fa partire la funzione (es. "è arrivato un nuovo file nel Blob Storage").

Il Binding è il modo dichiarativo di connettere dati in input o output.

Immagina di voler salvare il risultato di un'elaborazione su un database Cosmos DB.

Invece di scrivere 50 righe di codice per connetterti al DB, aggiungi semplicemente un attributo di Output Binding alla tua funzione.

Il runtime di Azure si occupa di gestire la connessione e la scrittura.

Questo riduce drasticamente il debito tecnico legato al codice infrastrutturale.

Il tuo codice si concentra solo sulla business logic pura.

Tuttavia, un Architetto deve conoscere i limiti: i binding sono ottimi per operazioni semplici, ma per scenari complessi (transazioni distribuite, query avanzate) potrebbe essere necessario usare i client SDK nativi per avere un controllo più granulare.

Saper scegliere quando usare la magia dei binding e quando "sporcarsi le mani" con l'SDK è ciò che distingue un professionista.

Microsoft Azure prezzi: capire i modelli Consumption, Premium e Dedicated

Parlare di cloud senza parlare di costi è irresponsabile.

Quando si cercano informazioni su "Microsoft Azure prezzi", spesso si finisce in tabelle confuse. Per le Functions, la scelta del piano determina non solo il costo, ma le capacità architetturali.

Esistono tre modelli principali, e scegliere quello sbagliato può costarti caro (in denaro o in performance).

1. Consumption Plan (Pay-per-use)

È il vero serverless. Paghi solo quando la funzione gira.

Vantaggi: Scala a zero. Costo nullo se nessuno la usa. Scalabilità automatica massiva.

Svantaggi: Cold Start (ne parliamo tra poco). Nessuna integrazione VNET (non puoi accedere a risorse in una rete privata facilmente). Timeout massimo di 10 minuti.

2. Premium Plan

È il serverless "di lusso".

Vantaggi: Niente Cold Start (istanze pre-riscaldate). Integrazione VNET completa. Hardware più potente. Durata illimitata (teoricamente).

Svantaggi: Costo minimo mensile fisso (paghi almeno un'istanza sempre accesa), che può essere significativo per progetti piccoli.

3. Dedicated (App Service Plan)

Esegui le funzioni su macchine virtuali dedicate (come un sito web classico).

Vantaggi: Costo prevedibile (flat rate). Puoi riutilizzare risorse che stai già pagando per altri servizi.

Svantaggi: Non c'è la scalabilità elastica rapida del serverless. Se le risorse finiscono, le funzioni rallentano.

Un Architetto deve saper fare i conti: se hai un carico costante e prevedibile 24/7, il piano Dedicated potrebbe costare meno del Consumption.

Se hai picchi improvvisi e lunghi periodi di inattività, il Consumption è imbattibile.

Non lasciare che la scelta del piano sia un dettaglio dell'ultimo minuto: è una decisione di design fondamentale.

Come sfruttare il livello Azure gratis per prototipare a costo zero

Molti ignorano che Microsoft offre un livello generoso per iniziare.

Cercare "Azure gratis" non è da spilorci, è da strateghi. Il piano Consumption include mensilmente 1 milione di richieste gratuite e 400.000 GB-secondi di consumo di risorse.

Questo significa che per prototipi, ambienti di sviluppo personali o microservizi con carico moderato, l'infrastruttura compute è letteralmente a costo zero.

Come sfruttarlo al meglio per prototipare?

  • Sperimentazione architetturale: Puoi creare diverse architetture (es. una basata su code, una su HTTP) e testarle senza dover chiedere budget al management.
  • Ambienti di Sandbox: Ogni sviluppatore può avere la propria istanza di Azure Func isolata per testare le feature prima del merge.
  • Tool interni: Automazioni per il team (es. bot di Slack, pulizia automatica di risorse) spesso rientrano ampiamente nel tier gratuito.

Attenzione però: "gratis" si applica alla computazione. Lo Storage Account necessario per far girare le funzioni, il traffico di rete (Egress) e servizi accessori come Application Insights si pagano a parte (anche se parliamo di cifre irrisorie per piccoli volumi).

Sfruttare il livello gratuito ti permette di fallire velocemente e imparare senza rischi finanziari.

Il problema del Cold Start: strategie avanzate per garantire le performance

Il "Cold Start" è il nemico numero uno delle architetture serverless nel piano Consumption.

Quando la tua funzione non viene usata per un po' (circa 20 minuti), Azure "spegne" l'infrastruttura sottostante per risparmiare risorse.

Alla richiesta successiva, il cloud deve: allocare un server, scaricare il pacchetto della tua app, avviare il runtime della funzione ed eseguire il tuo codice.

Questo processo può richiedere da pochi secondi (per C# o Python) fino a 10-20 secondi (per Java o framework pesanti).

Per un processo batch notturno, non importa. Per un'API che serve l'interfaccia utente, 5 secondi di attesa sono inaccettabili.

Quali sono le strategie avanzate per gestirlo?

  • Ottimizzazione del codice: Riduci le dipendenze. Caricare librerie enormi all'avvio rallenta tutto. Usa la "Dependency Injection" in modo intelligente (es. Singleton per connessioni DB) per riutilizzare le connessioni nelle chiamate successive (Warm Start).
  • Piano Premium: Se la latenza è critica, paga per il piano Premium. Mantiene istanze "pre-warmed" pronte a scattare immediatamente. È la soluzione costosa ma definitiva.
  • Strategie "Keep-Alive" (Sconsigliate ma usate): Creare una funzione timer che chiama la tua API ogni 5 minuti per tenerla sveglia. Funziona parzialmente, ma non garantisce la scalabilità su più istanze e combatte contro la natura stessa del platform.

Un Architetto non ignora il Cold Start: lo analizza, decide se è tollerabile per il caso d'uso specifico e sceglie la strategia di mitigazione adeguata al budget.

Durable Functions: gestire flussi di lavoro complessi e stateful

Le funzioni serverless sono, per definizione, "stateless" (senza stato). Eseguono un compito e dimenticano tutto.

Ma il mondo reale è fatto di processi complessi: "Ordina prodotto" -> "Attendi pagamento" -> "Se pagato, spedisci" -> "Altrimenti annulla".

Gestire questo con funzioni standard richiede un database esterno e una logica complessa di coordinamento.

Qui entra in gioco l'estensione Durable Functions.

Ti permette di scrivere "Orchestratori" nel codice.

Un Orchestrator è una funzione che definisce il flusso di lavoro. Può chiamare altre funzioni, attendere il loro risultato, dormire per giorni, e riprendere esattamente da dove aveva lasciato.

La magia? Lo stato viene salvato automaticamente nello Storage Account.

Questo abilita pattern potenti come:

  • Function Chaining: Esegui A, passa il risultato a B, poi a C.
  • Fan-out/Fan-in: Esegui 1000 funzioni in parallelo e attendi che TUTTE abbiano finito per aggregare il risultato.
  • Human Interaction: Invia una mail di approvazione e attendi (anche settimane) che il manager clicchi un link prima di proseguire il processo.

Durable Functions trasforma Azure Func da semplice esecutore di script a motore di workflow enterprise.

Nel Corso Architetto Software approfondiamo come usare questi pattern per sostituire sistemi legacy complessi e costosi con codice pulito e manutenibile.

Sicurezza e monitoraggio: proteggere le API e usare Application Insights

Lanciare una funzione pubblica senza protezione è come lasciare la porta di casa aperta in centro città.

La sicurezza in Azure Func si gestisce a più livelli.

A livello base, ci sono le Function Keys (chiavi segrete nell'URL), ma per un'architettura seria non bastano.

L'approccio corretto prevede l'integrazione con Azure Active Directory (Entra ID) per l'autenticazione, o l'uso di Azure API Management come scudo frontale per gestire rate limiting, IP filtering e policy di sicurezza avanzate.

Inoltre, non salvare mai le stringhe di connessione nel codice. Usa sempre Azure Key Vault e referenzia i segreti tramite le impostazioni dell'app.

E poi c'è il monitoraggio.

In un sistema distribuito, non puoi fare "debug" guardando la console. I log sono sparsi su decine di istanze effimere.

Application Insights è obbligatorio, non opzionale.

Ti offre una mappa delle dipendenze in tempo reale: vedi quale funzione ha chiamato quale database, quanto tempo ha impiegato e dove si è verificato l'errore.

Senza Application Insights, sei cieco. Con esso, hai i raggi X sul tuo sistema.

Un Architetto imposta gli alert proattivi: vuoi sapere se le eccezioni superano l'1% prima che i clienti inizino a chiamare il supporto.

Quando NON usare Azure Func: limiti architetturali e analisi dei trade-off

L'onestà intellettuale è la dote principale di un Architetto. Azure Func non serve a tutto.

Ci sono scenari in cui usarle è un errore costoso o tecnicamente sbagliato.

  1. Processi a lunga durata (long running)
    Nel piano Consumption, hai un hard limit di 10 minuti. Se devi elaborare un video per 2 ore, usa Azure Batch o Container Instances, non una Function.
  2. Carico costante e prevedibile ad alto volume
    Se hai un'API che riceve costantemente 10.000 richieste al secondo 24/7, il serverless potrebbe costarti molto di più di un cluster Kubernetes (AKS) o di App Service ben dimensionati. Il serverless si paga "a consumo", e se il consumo è altissimo, il prezzo sale.
  3. Controllo estremo dell'ambiente
    Se la tua applicazione richiede l'installazione di font custom, driver GDI legacy o configurazioni particolari del sistema operativo, il modello PaaS/FaaS ti bloccherà. In quel caso, i Container sono la scelta migliore.
  4. Latenza ultra-bassa costante
    Per applicazioni di trading ad alta frequenza o gaming real-time, l'overhead dell'HTTP e i potenziali cold start rendono le Functions inadatte.

L'analisi dei trade-off è ciò che facciamo ogni giorno. Sapere quando non usare una tecnologia è importante quanto sapere come usarla.

Il ruolo dell'Architetto Software nella governance del cloud ibrido

Il cloud non si gestisce da solo. Azure Func è uno strumento potente, ma senza una visione d'insieme porta alla frammentazione.

Il ruolo dell'Architetto Software non è più quello di disegnare diagrammi UML su carta.

Oggi l'Architetto è il garante della governance.

Deve definire le policy per impedire ai costi di esplodere. Deve disegnare le reti (VNET) per garantire che i dati sensibili non viaggino mai su internet pubblica. Deve scegliere i pattern di integrazione per unire il vecchio mondo on-premise con il nuovo mondo cloud.

Azure Func spesso agisce da ponte in scenari di cloud ibrido, connettendo ERP legacy aziendali con servizi SaaS moderni.

La tecnologia è facile. Le persone e i processi sono difficili.

La sfida vera non è scrivere la funzione, ma orchestrare il team, gestire il ciclo di vita DevOps, garantire la sicurezza e mantenere il sistema evolvibile nel tempo.

I tutorial online ti insegnano il "come". I competitor si limitano a venderti certificazioni teoriche.

Ma nessuno ti insegna a pensare e decidere in scenari complessi e reali dove il budget è limitato e i rischi sono alti.

Nel Corso Architetto Software, colmiamo questo vuoto.

Trasformiamo senior developer in leader tecnici capaci di guidare l'azienda nelle scelte tecnologiche, usando strumenti come Azure Func non per moda, ma per creare vantaggio competitivo reale.

Non accontentarti di far funzionare il codice. Impara a governare il sistema.

Il prossimo passo per la tua carriera inizia qui.

Lascia i tuoi dati nel form qui sotto

Matteo Migliore

Matteo Migliore è un imprenditore e architetto software con oltre 25 anni di esperienza nello sviluppo di soluzioni basate su .NET e nell'evoluzione di architetture applicative per imprese e organizzazioni di alto profilo.

Nel corso della sua carriera ha collaborato con realtà come Cotonella, Il Sole 24 Ore, FIAT e NATO, guidando team nello sviluppo di piattaforme scalabili e modernizzando ecosistemi legacy complessi.

Ha formato centinaia di sviluppatori e affiancato aziende di ogni dimensione nel trasformare il software in un vantaggio competitivo, riducendo il debito tecnico e portando risultati concreti in tempi misurabili.

Stai leggendo perché vuoi smettere di rattoppare software fragile.Scopri il metodo per progettare sistemi che reggono nel tempo.