
Nel precedente articolo abbiamo visto cosa è Apache Airflow, e come gestire (almeno le basi) la tecnologia che consente di generare ed eseguire i container. Ci siamo lasciati con una domanda: come Azure supporta tutto questo?
Il supporto di Azure alla containerizzazione
In effetti c’è da dire che Azure supporta i container in molte forme diverse, offrendo servizi più o meno complessi in base alla necessità.
- Azure Kubernetes Service (AKS): AKS è un servizio gestito di Kubernetes che semplifica il deployment, la gestione e le operazioni di container Kubernetes. Offre scalabilità automatica, aggiornamenti senza downtime e un’integrazione perfetta con altri servizi Azure, rendendolo ideale per eseguire applicazioni containerizzate in produzione.
- Azure Container Instances (ACI): ACI consente di eseguire container Docker senza necessità di gestire l’infrastruttura sottostante. È possibile avviare rapidamente container on-demand, pagando solo per le risorse effettivamente utilizzate. ACI è particolarmente utile per carichi di lavoro temporanei o bursting.
- Azure Container Apps: Azure Container Apps è un servizio completamente gestito per eseguire applicazioni e microservizi containerizzati. È progettato per il deployment e la gestione di applicazioni moderne con scalabilità automatica basata su eventi, e supporta linguaggi e framework comuni. Azure Container Apps integra funzionalità di gestione del traffico, aggiornamenti e rollback, offrendo un’esperienza di sviluppo e deployment semplificata.
- Azure App Service: Questo servizio supporta il deployment di container personalizzati, consentendo di eseguire applicazioni web e API containerizzate. Azure App Service gestisce l’infrastruttura, il bilanciamento del carico, il scaling e gli aggiornamenti, offrendo un’esperienza di deployment semplificata.
Infine, a prescindere da quale sia il servizio scelto è necessario avere un luogo dove persistere i container creati, un repository o registro. Per questo esiste Azure Container Registry (ACR). ACR è un registry Docker privato che consente di archiviare e gestire le immagini dei container. Supporta l’integrazione con AKS, ACI e altri servizi Azure, facilitando il flusso di lavoro di continuous integration/continuous deployment (CI/CD).
Nel nostro caso, utilizzeremo due servizi: Azure App Service e Azure Container Apps. Perchè due servizi? Perché Airflow, come detto prima, è diviso in alcuni componenti principali. E per avere una soluzione disaccoppiata (e pronta per essere scalabile) andremo a pubblicare il webserver sul servizio Azure App Service e lo scheduler sul servizio Azure Container App.
Entrambi i casi sono vantaggiosi nel caso di carichi di lavoro medi, in quanto gestiscono automaticamente tutta l’infrastruttura sottostante, andando a semplificare notevolmente la fase di pubblicazione e aggiornamento dei container.
Un ulteriore modo per eseguire Airflow su Azure
Un altro modo per eseguire Apache Airflow su Azure è tramite Azure Data Factory Workflow Orchestration Manager. Anche se non lo vedremo in questo articolo, era corretto citarlo in quanto sistema completamente gestito.
Questo servizio integrato consente di eseguire e gestire i DAG di Apache Airflow in un ambiente completamente gestito, combinando la scalabilità, la sicurezza e la facilità di gestione di Azure Data Factory con la flessibilità e l’estensibilità di Airflow.
Vantaggi di Azure Data Factory Workflow Orchestration Manager
- Setup Automatico: Configura automaticamente l’ambiente di Airflow, semplificando l’installazione.
- Scalabilità Automatica: Regola automaticamente il numero di worker in base al carico di lavoro.
- Autenticazione Integrata: Utilizza Azure Active Directory per l’autenticazione e il controllo degli accessi.
- Sicurezza: I dati sono criptati sia con chiavi gestite da Azure che con chiavi gestite dal cliente.
- Aggiornamenti e Patch Automatizzati: Mantiene Airflow aggiornato con le ultime versioni e patch.
- Monitoraggio: Integra i log e le metriche di Airflow con Azure Monitor per una facile diagnostica e monitoraggio.
Per maggiori informazioni, questo è il Link alla pagina.
Pubblicazione dei componenti webserver e scheduler di Airflow
Visto quindi cosa è Airflow, cosa sono i container, ed alcuni cenni per capire come lavorare con Docker, c’è da chiedersi come mettere tutto insieme da un punto di vista pratico.
Nella soluzione che solitamente utilizzo nelle attività di progettazione e sviluppo, mi trovo ad avere una cartella di lavoro strutturata più o meno nel modo seguente:
- cartella “dags”: questa cartelle contiene i dag di airflow che saranno poi eseguiti da Airflow
- cartella “processes / app”: questa cartella contiene i processi python veri e propri, come in questo caso, deputati alle operazioni di ETL. Ho seguito questo approccio in modo da tenere separato il codice di Airflow da quello dei processi, nel caso in un secondo momento fosse necessario pubblicarli altrove o con altre tecnologie.
- “airflow.cfg”: questo è un file che sarà utile nella costruzione dell’immagine del container. Contiene infatti la configurazione di Airflow ed è il posto dove solitamente si imposta il logging.
- “requirements.txt”: questo file è l’elenco dei pacchetti da installare insieme ad Airflow. Infatti alcuni processi potrebbero avere necessità di pacchetti aggiuntivi non installati di default con airflow.
- dockerfile: uno o più dockerfile (nel nostro caso ne avremo due, uno per generare l’immagine del web server ed uno per generare l’immagine dello scheduler)
- docker-compose: il docker-compose è un file che serve nel caso si vogliano avviare più container che devono comunicare insieme. Nel caso di un’installazione sul servizio AKS, sarebbe necessario. Ma nel nostro caso, sfrutteremo i servizi detti in precedenza per mantenere un’architettura più snella e leggera, che ne semplifichi la gestione.

Il cuore del sistema è racchiuso nei dockerfile e nei comandi docker. In questo caso il docker file utilizzato (per lo scheduler, per il web server è possibile semplificarlo), contiene le istruzioni per partire dall’immagine airflow, copiare le cartelle dei DAG e dei processi, installare le dipendenze python, fare l’override della configurazione airflow ed avviare il componente corretto (scheduler o webserver).
Ecco il file airflow:
FROM apache/airflow:2.9.2-python3.10
ENV AIRFLOW_HOME=/usr/local/airflow
ENV AIRFLOW__CORE__EXECUTOR=LocalExecutor
ENV AIRFLOW__WEBSERVER__EXPOSE_CONFIG=True
ENV AIRFLOW__LOGGING__REMOTE_LOGGING=True
ENV AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER=wasb-airflow-logs
ENV AIRFLOW__AZURE_REMOTE_LOGGING__REMOTE_WASB_LOG_CONTAINER=airflow-logs
USER root
RUN mkdir -p ${AIRFLOW_HOME} && chown -R airflow: ${AIRFLOW_HOME}
USER airflow
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
COPY dags/ $AIRFLOW_HOME/dags/
COPY app/ $AIRFLOW_HOME/app/
COPY .env.prod $AIRFLOW_HOME/app/.env
COPY airflow.cfg $AIRFLOW_HOME/
WORKDIR $AIRFLOW_HOME
ENTRYPOINT ["/entrypoint.sh"]
CMD ["airflow", "scheduler"]
Ma cosa fa nello specifico?
Docker file Airflow
1. Base Image
FROM apache/airflow:2.9.2-python3.10
Questa riga specifica l’immagine di base da cui partire. Stiamo utilizzando una versione di Apache Airflow con Python 3.10. Questo assicura che abbiamo un ambiente già predisposto per eseguire Airflow.
2. Variabili di Ambiente
ENV AIRFLOW_HOME=/usr/local/airflow
ENV AIRFLOW__CORE__EXECUTOR=LocalExecutor
ENV AIRFLOW__WEBSERVER__EXPOSE_CONFIG=True
ENV AIRFLOW__LOGGING__REMOTE_LOGGING=True
ENV AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER=wasb-airflow-logs
ENV AIRFLOW__AZURE_REMOTE_LOGGING__REMOTE_WASB_LOG_CONTAINER=airflow-logs
Queste righe impostano le variabili di ambiente necessarie per configurare Airflow. AIRFLOW_HOME definisce la directory principale di Airflow, mentre le altre variabili configurano l’esecutore, il logging remoto e altri parametri importanti.
3. Permessi Utente
USER root
RUN mkdir -p ${AIRFLOW_HOME} && chown -R airflow: ${AIRFLOW_HOME}
USER airflow
In questa sezione, creiamo la directory principale di Airflow e ne modifichiamo i permessi per assicurare che l’utente airflow possa scriverci. Torniamo poi all’utente airflow per eseguire le restanti operazioni.
4. Installazione delle Dipendenze
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
Copiamo il file requirements.txt nel container e installiamo le dipendenze Python specificate. Utilizziamo –no-cache-dir per evitare di conservare cache inutili, riducendo così l’immagine finale.
5. Script di Entrypoint
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
Copiamo uno script di entrypoint nel container e lo rendiamo eseguibile. Questo script si assicura che il database sia pronto prima di eseguire Airflow.
6. Copia dei File Necessari
COPY dags/ $AIRFLOW_HOME/dags/
COPY app/ $AIRFLOW_HOME/app/
COPY .env.prod $AIRFLOW_HOME/app/.env
COPY airflow.cfg $AIRFLOW_HOME/
Copiamo i file e le directory necessari nel container, inclusi i DAGs (Direct Acyclic Graphs), le configurazioni e le variabili di ambiente.
7. Directory di Lavoro e Comandi Finali
WORKDIR $AIRFLOW_HOME
ENTRYPOINT ["/entrypoint.sh"]
CMD ["airflow", "scheduler"]
Impostiamo la directory di lavoro e definiamo il comando di entrypoint. L’entrypoint script si occupa di inizializzare il database e creare utenti, mentre il comando CMD avvia lo scheduler di Airflow.
Script di Entrypoint (entrypoint.sh)
Ecco uno script di esempio che assicura che il database sia pronto prima di avviare Airflow:
#!/bin/sh
# Attendi che il database sia disponibile
while ! nc -z myserver.mysql.database.azure.com 3306; do
echo "Aspettando il database..."
sleep 3
done
# Inizializza il database
airflow db migrate
# Crea un utente admin se non esiste
airflow users create --username [adminName] --password "$AIRFLOW_ADMIN_PASSWORD" --firstname First --lastname Last --role Admin --email admin@example.com || true
exec "$@"
Build e pubblicazione sul registro Azure
Ora che abbiamo il dockerfile per realizzare l’immagine dello scheduler (per il componente web server il ragionamento è analogo, utilizzando un dockerfile specifico), è il momento di invocare Docker per “impacchettare” il tutto realizzando l’immagine:
docker build --no-cache -t airflow-scheduler -f Dockerfile-scheduler .
Come visto prima, questo comando esegue la build dell’immagine, andando a specificare anche il dockerfile da utilizzare.
Ma come è possibile pubblicare l’immagine sul registro Azure?
Push dell’immagine sul registro container di Azure (ACR)
La prima cosa da fare è istanziare la risorsa Azure Container Registry. Questo sarà un registro privato per l’azienda che conterrà tutte le immagini del parco software.
Una volta creata la risorsa, nel menu “Repository” si troveranno tutte le immagini.

Per poter eseguire il push delle immagini è adesso necessario:
- installare AZ CLI (la command line interface di Azure)
- eseguire il login (az login)
- eseguire il login sul registro container (az acr login –name [nome account]) dove [nome account] è il nome del registro appena creato.
- eseguire il tag dell’immagine. Il comando docker tag viene utilizzato per assegnare un nuovo tag a un’immagine Docker esistente. I tag sono etichette leggibili che aiutano a identificare e organizzare le immagini. Questo comando non crea una nuova immagine; semplicemente assegna un nuovo nome o tag a un’immagine esistente, rendendo più facile il riferimento e la gestione delle immagini. Il nome del tag deve essere coerente con il nome dell’account di ACR, ad esempio:
docker tag airflow-scheduler [nome ACR].azurecr.io/airflow-scheduler
Adesso, è possibile eseguire il push sul registro tramite il comando:
docker push [nome ACR].azurecr.io/airflow-scheduler
Ora che abbiamo le immagini dello scheduler e del web server (non abbiamo scritto il codice, ma per estensione deriva da quello dello scheduler) caricate sul registro privato è il momento di utilizzarle.
Pubblicazione dello scheduler su Azure Container App
Andremo a pubblicare lo scheduler sul servizio Azure Container App.
Questo servizio, come detto prima, permette di avere una gestione più semplificata rispetto ad un intero cluster Kubernetes pur mantenendo alcune potenti funzionalità come lo scaling delle risorse, il monitoraggio, e la gestione del failure del container.
Durante la creazione della risorsa, le informazioni fondamentali saranno il registro dal quale eseguire il PULL (prelievo) dell’immagine, l’immagine stessa ed il tag (la versione).
Oltre a questo è possibile definire alcune opzioni in merito alla rete, al monitoring ed altro.


Una volta eseguito il deploy della risorsa e del container, è possibile accedere all’amministrazione come si vede nell’immagine di seguito.
A questo punto è possibile vedere lo stream del log (nel blade Monitoring) per capire che il container è stato avviato e sta già “lavorando”.


Pubblicazione del web server su Azure App Service
Anche in questo caso è possibile creare una risorsa Azure App Service ed eseguire un container.
Generalmente il servizio App Service è il più adatto per le applicazioni web come quella di controllo dello scheduler.
Durante la creazione della risorsa è infatti possibile scegliere di eseguire la pubblicazione di un container anziché codice sorgente, e questo permette di scegliere, come nel caso precedente, il registro e l’immagine desiderata.


Inoltre proprio come gli altri servizi, è possibile eseguire il monitoraggio della risorsa integrandolo con servizi come Application Insight per analizzare i log applicativi.
Anche in questo caso, una volta avviato l’app service, il container viene inizializzato ed eseguito.
Trattandosi di una web app, il servizio App Service mette automaticamente a disposizione un DNS così da poter raggiungere la console di amministrazione web da browser.
Il database
Scheduler e web server comunicano tra loro tramite un database. Nel caso specifico, spesso mi trovo ad utilizzare il servizio MySQL server di Azure, completamente gestito.
Il database viene inizializzato tramite lo script dell’entry point presente nei dockerfile.
Azure blob storage per la gestione dei log
Una nota importante va ai log.
Ogni task di airflow registra un log di esecuzione, fondamentale per il monitoraggio.
Quando scheduler e web server vengono eseguiti nel solito ambiente, ad esempio un server on-premise, la scrittura dei log da parte dello scheduler e la loro lettura da parte del web server è immediata e non necessita di altre infrastrutture.
In un caso come quello dell’esempio però, dove i container vengono eseguiti in ambienti diversi e disgiunti, è necessario aggiungere un parte di infrastruttura in comune per la scrittura e lettura dei logs.
Airflow mette a disposizione la possibilità di attivare un flag chiamato “remote logging” che permette di autenticare scheduler e web server presso uno storage di Azure (ma anche S3 o GCP). In questo modo lo scheduler e il web server possono avere accesso alle solite informazioni.
Per impostare questa funzionalità ti rimando alla documentazione ufficiale qui.
Conclusione
In sintesi, Apache Airflow integrato con la containerizzazione su Azure rappresenta una soluzione estremamente efficace per l’orchestrazione e l’automazione dei flussi di lavoro dei dati. La capacità di scalare automaticamente, la facilità di gestione e l’integrazione nativa con altri servizi Azure offrono un valore significativo per le organizzazioni che desiderano ottimizzare le loro pipeline di dati. Adottare questa combinazione permette non solo di migliorare l’efficienza operativa, ma anche di ridurre i costi e aumentare la flessibilità nella gestione dei dati.
Implementare Apache Airflow su Azure significa approfittare delle migliori pratiche di data engineering moderne, assicurando che le applicazioni siano portabili, scalabili e manutenibili. Con i servizi di Azure, come AKS, ACI, e Azure Container Apps, è possibile configurare un ambiente robusto che soddisfi le esigenze di carichi di lavoro variabili e complessi.
Se sei interessato a saperne di più su come queste tecnologie possono essere applicate al tuo contesto aziendale, o se hai bisogno di supporto per implementare queste soluzioni, non esitare a contattarmi o ad approfondire la consulenza che offro alle aziende. Sono a tua disposizione per offrirti consulenza e assistenza personalizzata per sfruttare al meglio il potenziale dei tuoi dati.
Alla prossima informazione!