Nel precedente articolo abbiamo esaminato diverse funzionalità DevOps di Snowflake. Si tratta dei singoli mattoni che consentono di gestire l'infrastruttura Snowflake come codice, in modo automatizzato.
In questo articolo vedremo come combinare tali funzionalità per costruire pipeline CI/CD che automatizzano il deploy dell'infrastruttura Snowflake, sfruttando feature native come CREATE OR ALTER, l'integrazione con Git o EXECUTE IMMEDIATE FROM. Useremo GitHub come servizio di repository e GitHub Actions come orchestratore.
Iniziamo con una breve introduzione ai workflow di GitHub Actions.
I workflow di GitHub Actions
GitHub Actions è una potente piattaforma CI/CD integrata direttamente in GitHub, che permette agli sviluppatori di automatizzare i flussi di lavoro tramite pipeline event-driven. Si basa sul concetto di workflow definiti in file YAML e salvati nella directory .github/workflows/ del repository. Ogni workflow può comprendere uno o più job che vengono eseguiti su macchine virtuali chiamate runner. Questi runner possono essere ospitati da GitHub, senza alcun onere di gestione. Quando il workflow viene attivato, un runner viene assegnato automaticamente alla pipeline; in alternativa, è possibile utilizzare un runner self-hosted.
Per creare una pipeline occorre definire alcuni elementi chiave:
Trigger
Può essere un evento nel repository (ad esempio push, pull_request, ecc.), un cron job pianificato oppure un'attivazione manuale.
Ambiente del runner
Specifica dove verrà eseguito il codice, ovvero il sistema operativo del runner. Esempi tipici sono ubuntu-latest o windows-latest.
Struttura dell'automazione
A questo punto va definita l'automazione vera e propria, ossia la serie di step da eseguire. Ricordi che, a ogni esecuzione, la macchina runner parte da uno stato pulito predefinito. Occorre quindi predisporre l'ambiente per il job specifico: installare i linguaggi richiesti (ad esempio Python), recuperare il codice dal repository e leggere le variabili d'ambiente. I singoli step possono essere comandi shell, esecuzione di script o action predefinite e possono sfruttare informazioni contestuali, come ${{ github.event_name }} o ${{ secrets.SF_ACCOUNT_ID }}.
Queste caratteristiche di base rendono GitHub Actions particolarmente adatto a pipeline CI/CD in cui è necessario gestire in modo sicuro le credenziali del database, eseguire script SQL, propagare modifiche tra ambienti e tracciare chi ha effettuato i cambiamenti, il tutto con l'integrazione nativa del version control.
Pipeline CI/CD di Snowflake per l'infrastruttura dell'account
Lavoreremo in locale con VS Code, dove svilupperemo gli script SQL e la definizione YAML del workflow di GitHub Actions. Una volta pronto il tutto, faremo il push delle modifiche nel repository remoto, creeremo una pull request e ne effettueremo il merge nel branch dev. Come illustrato nello schema, sfrutteremo diverse funzionalità di Snowflake per arrivare al risultato. Creeremo inoltre due versioni della pipeline CI/CD:
1 Con l'estensione Git di Snowflake In questo approccio, GitHub Actions funge esclusivamente da orchestratore. Grazie all'estensione Git possiamo eseguire tutto il codice direttamente all'interno di Snowflake.
2 Eseguendo il codice su un runner GitHub tramite SnowCLI Se preferisce non utilizzare l'estensione Git di Snowflake, esiste un'alternativa: eseguire il codice direttamente sulla macchina runner tramite la Snowflake Command Line Interface ( SnowCLI). Vedremo anche questa opzione.
Creazione dell'infrastruttura Snowflake
Creiamo innanzitutto la nostra infrastruttura e salviamola in diversi file sql.
I nostri warehouse:
USE ROLE sysadmin;
--ELT warehouse definition
CREATE WAREHOUSE IF NOT EXISTS elt WITH
WAREHOUSE_SIZE = XSMALL
AUTO_SUSPEND = 60
AUTO_RESUME = True
INITIALLY_SUSPENDED = True;
--developers warehouse definition
CREATE WAREHOUSE IF NOT EXISTS developers WITH
WAREHOUSE_SIZE = SMALL
AUTO_SUSPEND = 120
AUTO_RESUME = True
INITIALLY_SUSPENDED = True;
Ci serve anche un ruolo:
/*
* Role name: LOADER
* Description: Used by ELT pipelines to load data */
*/
USE ROLE securityadmin;
CREATE OR ALTER ROLE loader;
E infine il database e lo schema:
/*
* DB name: DEVOPS
* Description: Used for showcasing Snowflake DevOps capabilities
*/
use role sysadmin;
create or alter database devops;
------------------------SCHEMAS------------------------
/*
* Schema name: ADMIN
* Description: To keep all admin stuff at one place
*/
Espandi codice
Pipeline CI/CD basata sul Git Stage
Abbiamo preparato gli script SQL iniziali ed è ora di sviluppare il workflow di GitHub Actions. Questo workflow sfrutta l'estensione Git di Snowflake e si basa su un'integrazione attiva tra l'account Snowflake e il repository GitHub. Abbiamo spiegato come configurarla in un articolo dedicato all'~ integrazione Git di Snowflake ~.
name: Deploying Snowflake objects with CLI v1
env:
SNOWFLAKE_ACCOUNT: ${{ secrets.SF_ACCOUNT }}
SNOWFLAKE_USER: ${{ secrets.SF_USER }}
SNOWFLAKE_PASSWORD: ${{ secrets.SF_PASSWORD }}
SNOWFLAKE_DATABASE: ${{ secrets.SF_DATABASE }}
SNOWFLAKE_SCHEMA: ${{ secrets.SF_SCHEMA }}
SNOWFLAKE_ROLE: ${{ secrets.SF_ROLE }}
SNOWFLAKE_WAREHOUSE: ${{ secrets.SF_WAREHOUSE }}
on:
workflow_dispatch:
jobs:
deploy-Snowflake-changes:
Espandi codice
Analizziamo il codice nel dettaglio.
All'inizio configuriamo le variabili d'ambiente necessarie per la connessione a Snowflake. I valori vengono recuperati dai GitHub Secrets. Definiamo poi il trigger: in questo caso usiamo workflow_dispatch, il che significa che il workflow deve essere avviato manualmente dal repository.
Il resto è piuttosto lineare. Dobbiamo installare SnowCLI sulla macchina runner di GitHub per poter:
- connetterci a Snowflake
- lanciare i comandi richiesti
Esiste una ~ GitHub Action ~ nativa fornita da Snowflake che semplifica setup e gestione della connessione.
Per prima cosa sincronizziamo lo stage del repository Git di Snowflake con il repository remoto tramite il comando ALTER GIT REPOSITORY. In questo modo le ultime modifiche vengono importate direttamente nel Git stage all'interno di Snowflake.
A quel punto utilizziamo EXECUTE IMMEDIATE per eseguire il codice direttamente dai file SQL. Effettueremo il deploy di warehouse, ruoli, database e schemi. Ed è tutto: un workflow semplice ed efficace per distribuire automaticamente le modifiche alla propria infrastruttura Snowflake come codice.
Pipeline CI/CD con codice eseguito sul runner di GitHub
Costruiamo ora una pipeline analoga, ma questa volta eseguiremo tutto direttamente sulla macchina runner di GitHub, senza ricorrere al Git stage di Snowflake. Il Git stage è una funzionalità potente, ma presenta alcuni limiti: è di sola lettura e non è accessibile dai repository protetti da reti private. Questi vincoli possono essere ragioni valide per non utilizzare l'integrazione Git di Snowflake in determinati scenari. Ecco la nostra definizione di workflow YAML:
name: Deploying Snowflake objects with cli v2
env:
SNOWFLAKE_ACCOUNT: ${{ secrets.SF_ACCOUNT }}
SNOWFLAKE_USER: ${{ secrets.SF_USER }}
SNOWFLAKE_PASSWORD: ${{ secrets.SF_PASSWORD }}
SNOWFLAKE_DATABASE: ${{ secrets.SF_DATABASE }}
SNOWFLAKE_SCHEMA: ${{ secrets.SF_SCHEMA }}
SNOWFLAKE_ROLE: ${{ secrets.SF_ROLE }}
SNOWFLAKE_WAREHOUSE: ${{ secrets.SF_WAREHOUSE }}
on:
workflow_dispatch:
jobs:
deploy-Snowflake-changes:
name: Snowflake infrastructure deployment
Espandi codice
Vediamo le differenze rispetto alla versione precedente. Questa volta dobbiamo portare il codice dal repository remoto alla macchina runner. A questo scopo usiamo un'altra action, checkout, che in sostanza esegue il pull del codice dal remoto.
Possiamo quindi utilizzare di nuovo SnowCLI, ma stavolta eseguiamo il codice dai file presenti sulla macchina runner anziché da quelli nello stage del repository.
Possibili miglioramenti
Questo è un semplice esempio di come sviluppare una pipeline CI/CD di base per il deploy dell'infrastruttura Snowflake. C'è ampio margine per renderla più "production ready". In un ambiente reale avrebbe:
- pipeline distinte per ciascun ambiente (dev, prod)
- trigger su eventi push e pull request limitati a branch specifici
- step diversi per gli eventi push e per gli eventi pull request
Sarebbe utile poter contare su uno step di "plan", come in Terraform, che mostri quali risorse verranno create, aggiornate o eliminate prima di applicare le modifiche. Mi auguro di vedere presto una funzionalità analoga anche tra le feature native di Snowflake.
Conclusioni
In questo articolo abbiamo visto come utilizzare le funzionalità DevOps native di Snowflake per continuous integration e continuous deployment. Abbiamo implementato una pipeline CI/CD basata su un workflow di GitHub Actions per distribuire gli oggetti dell'infrastruttura Snowflake come codice, direttamente dal repository remoto, semplicemente effettuando il push degli aggiornamenti dalle macchine locali al repo.
Si conclude qui la nostra serie dedicata al DevOps in Snowflake, che abbiamo affrontato in tre articoli:
- Un'analisi approfondita dell'integrazione Git di Snowflake
- CI/CD e DevOps in Snowflake (Parte 1): panoramica completa di funzionalità e strumenti
- CI/CD e DevOps in Snowflake (Parte 2): guida pratica all'implementazione
Tomáš Sobotík·Senior Data Engineer & Snowflake SME presso Norlys
Tomas è uno Snowflake Data SuperHero di lunga data e un esperto a 360 gradi di Snowflake. Vanta oltre un decennio di esperienza nel mondo dei dati, durante il quale ha ricoperto i ruoli di Snowflake data engineer, architect e admin in numerosi progetti, attraversando settori e tecnologie diversi. Tomas è un membro di riferimento della community, dove condivide attivamente le proprie competenze e ispira gli altri. È inoltre istruttore O'Reilly e conduce sessioni di formazione live online.