Pipeline CI/CD per le applicazioni di elaborazione dati su Azure Parte 1 Istanze di container

Pipeline CI/CD per le applicazioni di elaborazione dati su Azure - Parte 1 Istanze di container

Immagine generata con The AI Comic Factory: https://huggingface.co/spaces/jbilcke-hf/ai-comic-factory

Una Guida Passo-Passo per la Distribuzione di Contenitori Docker con GitHub Actions

Introduzione

Creare e distribuire manualmente risorse su Azure e altri provider di cloud è relativamente facile e potrebbe, in alcuni casi, essere sufficiente. Tuttavia, spesso le risorse distribuite avranno bisogno di cambiare nel tempo, il che richiederà un sacco di lavoro extra per la manutenzione e la ridistribuzione delle risorse. Per automatizzare queste attività, i programmatori e i professionisti dei dati possono invece utilizzare un approccio di infrastruttura come codice (IaC) e creare pipeline per l’integrazione continua e la distribuzione (CI/CD). Questo approccio consente ai programmatori di scrivere codice che definisce e ridistribuisce automaticamente le risorse ogni volta che vengono apportate modifiche.

In questa guida passo-passo, costruiremo delle pipeline per un’applicazione di elaborazione dati per svolgere i seguenti compiti:

  • Creare un registro dei contenitori
  • Creare e caricare un’immagine Docker nel registro
  • Creare un’istanza del contenitore che esegue il carico di lavoro di elaborazione dati
  • Abilitare l’accesso a “identità gestita” a Azure Key Vault, che consente all’applicazione di recuperare le chiavi di accesso ad altre risorse come gli account di archiviazione
  • Distribuire le risorse sopra menzionate su un ambiente di test e un ambiente di produzione utilizzando trigger diversi per l’esecuzione delle pipeline

Per iniziare

A scopo dimostrativo, l’applicazione stessa è costituita da uno script R molto semplice che carica un set di dati, stampa le prime righe e restituisce il set di dati a un account di archiviazione. Tieni presente che il codice dell’applicazione non è importante per il resto della pipeline e può essere facilmente sostituito dal tuo codice.

Per iniziare, avrai bisogno di un account Azure. Potresti anche voler installare Azure CLI sul tuo sistema locale. Tuttavia, puoi anche scegliere di eseguire comandi Azure CLI tramite Cloud Shell trovato nel portale di Azure.

Dato che la nostra applicazione trasferisce dati da e verso Azure Blob Storage e restituisce, potrebbe esserti utile installare Azure Storage Explorer, che semplifica un po’ il caricamento dei file e la verifica del corretto funzionamento dell’applicazione e del ritorno dei dati elaborati.

Passo 1: Clonare il Repository e Impostare le Risorse Statiche

Innanzitutto, dovrai clonare questo repository. Il file README spiega come fare questo utilizzando RStudio, ma sei libero di utilizzare il tuo IDE preferito.

Successivamente, utilizzando il Portale di Azure, crea le seguenti risorse:

  • un gruppo di risorse che conterrà tutte le altre risorse.
  • un account di archiviazione con un contenitore blob con due cartelle: una per i file di input e un’altra per i file di output. Nel nostro caso, queste dovrebbero chiamarsi rispettivamente ‘input’ e ‘output’. Memorizza un piccolo set di dati come file CSV chiamato ‘input_data.csv’ all’interno del contenitore di input.
  • un Key Vault in cui dovrai memorizzare la chiave di accesso primaria al tuo account di archiviazione come segreto.

Nel passaggio 3, avrai bisogno del nome del tuo Key Vault e del nome del tuo segreto che contiene la chiave di accesso primaria.

Passo 2: Collegare GitHub ad Azure

Per aggiornare le risorse di Azure, è necessario concedere a GitHub le autorizzazioni per farlo.

Per prima cosa, accedi al tuo account Azure utilizzando Azure CLI.

az login

Copia quindi il valore id dall’output JSON, che è l’ID della sottoscrizione. Incolla l’ID della sottoscrizione nel comando sottostante e eseguilo. Questo crea un “service principal” con controllo degli accessi basato sui ruoli, che può essere considerato come un utente che agisce per tuo conto durante la distribuzione o l’aggiornamento delle risorse con flussi di lavoro di GitHub Actions.

az ad sp create-for-rbac \      --name "your-app-name" \      --role Owner \      --scopes /subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group-name> \      --sdk-auth

Copia l’intero output JSON e vai al tuo repository GitHub e clicca su Impostazioni > Segreti e variabili > Azioni.

Crea un nuovo segreto di repository e chiamalo AZURE_CREDENTIALS. Incolla l’output JSON del comando precedente e salva.

Passaggio 3: modifica degli script

In questo scenario, stiamo distribuendo uno script R semplice che non fa molto. Pertanto, il Dockerfile è mantenuto anche molto semplice. Entrambi questi file dovranno ovviamente essere modificati in base alle tue esigenze e al tuo linguaggio di programmazione preferito. Tuttavia, se sei nuovo a tutto ciò, potrebbe essere utile far funzionare la tua pipeline con il codice così com’è prima di applicare il tuo codice.

Se scegli di procedere con lo script R attuale (script.R), dovrai solo modificare i valori {nome-keyvault}, {nome-chiave-accesso} e {nome-account-storage} (senza parentesi graffe).

Successivamente, modifica i seguenti valori sotto env: nei due file di flusso di lavoro chiamati workflow.yml e workflow_release_prod.yml nella directory .github/workflows/:

env:  RESOURCEGROUP_NAME: my-rg  REGISTRY_NAME: my-cr  SHORT_NAME: mycr  ACI_NAME: my-ci-test  KV_NAME: my-kv  ENVIRONMENT: test  CPU: 1  MEMORY: 1.5

Passaggio 4: esecuzione della pipeline e dell’istanza del contenitore

Quando saranno state apportate tutte le modifiche rilevanti e spinte nel ramo ‘main’, dovresti vedere la tua pipeline in esecuzione nel riquadro Azioni. Questo perché il flusso di lavoro è configurato con un trigger di ramo in modo che venga eseguito quando il ramo principale viene aggiornato.

Se non si verificano errori, la tua istanza del contenitore dovrebbe essere pronta per l’esecuzione in una decina di minuti circa. Vai al portale di Azure, trova la tua nuova istanza del contenitore e clicca su Avvia. Nel riquadro Log, potresti vedere lo script in esecuzione nella console. Al termine, verifica che sia stato creato un nuovo file cv chiamato output_data.csv nella cartella ‘output’ del tuo contenitore blob.

E questo è tutto! Se lo desideri, puoi ora attivare manualmente il secondo flusso di lavoro che crea un’istanza del contenitore identica destinata a carichi di lavoro di produzione.

Per capire cosa succede nella pipeline CI/CD, leggi la sezione sottostante.

Comprensione della logica del flusso di lavoro

Il file workflow.yml definisce cinque passaggi, o lavori, nella nostra pipeline che distribuisce risorse in un ambiente di test.

Immagine dell'autore

Prima passiamo le variabili d’ambiente impostate in precedenza necessarie per i passaggi rimanenti come outputs.

  vars:    runs-on: ubuntu-latest    outputs:      resource_group: ${{ env.RESOURCEGROUP_NAME }}      acr_name: ${{ env.REGISTRY_NAME }}      short_name: ${{ env.SHORT_NAME }}      aci_name: ${{ env.ACI_NAME }}      kv_name: ${{ env.KV_NAME }}      environment: ${{ env.ENVIRONMENT }}      cpu: ${{ env.CPU }}      memory: ${{ env.MEMORY }}    steps:      - run: echo "Esposizione delle variabili d'ambiente"

Nel secondo passaggio, creiamo o aggiorniamo un registro contenitori esistente. Nota che la chiave needs indica che questo passaggio deve attendere che il passaggio precedente sia completo. La chiave uses ci indica che è utilizzato un altro file per questo passaggio, mentre la chiave with viene utilizzata per passare i valori necessari. Dovremo anche passarene un segreto del repository.

  deploy-acr:    needs: vars    uses: ./.github/workflows/deploy_acr.yml    if: github.ref == 'refs/heads/main'    with:      environment: ${{ needs.vars.outputs.environment }}      resource_group: ${{ needs.vars.outputs.resource_group }}      acr_

All'inizio del file deploy_acr.yml utilizzato in questo passaggio, vediamo che lo script viene eseguito ogni volta che viene richiamato nel workflow, così come gli input richiesti che abbiamo fornito nel file workflow.yml.

on:   workflow_call:    inputs:      environment:        required: true        type: string      resource_group:        required: true        type: string      acr_name:        required: true        type: string    secrets:      azure_credentials:        required: true

Nella parte inferiore di deploy_acr.yml, abbiamo un processo multistep che esegue tre azioni predefinite. La prima azione effettua il checkout del repository, quindi effettuiamo il login su Azure utilizzando le credenziali del service principal che abbiamo creato e archiviato. Infine, utilizziamo l'azione chiamata azure/arm-deploy@v1 per distribuire il registro dei container. Si noti che questo passaggio utilizza Bicep, un linguaggio popolare per la configurazione e distribuzione delle risorse di Azure. In fondo a questo articolo, puoi trovare alcuni eccellenti risorse per approfondire Bicep.

jobs:  deploy-acr:    name: Deploy ACR    runs-on: ubuntu-latest    environment: ${{ inputs.environment }}    steps:      - uses: actions/checkout@v2      - uses: azure/login@v1        with:          creds: ${{ secrets.azure_credentials }}      - name: Deploy bicep        uses: azure/arm-deploy@v1        with:          resourceGroupName: ${{ inputs.resource_group }}          template: bicep/acr.bicep          parameters:            acrName=${{ inputs.acr_name }}            acrSku=Basic          failOnStdErr: false

Successivamente, viene creato e caricato un'immagine Docker nel registro nel terzo passaggio utilizzando il file build_push_container.yml, che esegue comandi Azure CLI per recuperare le credenziali per il registro dei container, così come i comandi Docker per creare e caricare l'immagine Docker.

Nel quarto passaggio, l'istanza del container viene fornita in base alla nostra immagine Docker. Questo passaggio viene effettuato tramite il file deploy_aci.yml, che a sua volta utilizza l'azione predefinita chiamata 'azure/aci-deploy@v1'.

Nell'ultimo passaggio utilizzando il file kv_access.yml, concediamo all'istanza del container il permesso di accedere alla key vault tramite un 'managed identity', il che significa che il container può recuperare segreti direttamente dal key vault senza utilizzare una chiave di accesso. Per ottenere ciò, dobbiamo aggiornare l'istanza del container distribuito utilizzando il comando Azure CLI az container create e fornire i vari parametri che abbiamo utilizzato in precedenza. Inoltre, forniamo l'impostazione seguente:

-- assign-identity -- scope ${{ steps.rg_id_step.outputs.rg_id }}

Come nota finale, potresti aver notato le seguenti righe in workflow.yml:

on:   push:    branches:       - main  workflow_dispatch:

Queste righe indicano quando e in quali condizioni il nostro pipeline dovrebbe essere eseguito. Nel nostro scenario, vogliamo che il pipeline venga eseguito quando vengono effettuate modifiche nel ramo 'main'. Inoltre, vogliamo poterlo eseguire manualmente. Ciò è reso possibile aggiungendo workflow_dispatch:. Nel pipeline di produzione definita in workflow_prod_release.yml, noterai che la distribuzione in produzione ha solo un trigger manuale. Ci sono molti altri modi per configurare come vengono attivati ​​i run della pipeline. Ad esempio, è possibile ignorare le modifiche in file o cartelle specifiche, in modo che solo le modifiche al codice dell'applicazione attivino nuove distribuzioni.

Per approfondire

Se desideri conoscere ulteriori informazioni su GitHub Actions e Bicep, ti consiglio vivamente le seguenti risorse della piattaforma MS Learn:

GitHub Actions

https://learn.microsoft.com/en-us/training/modules/introduction-to-github-actions/

https://learn.microsoft.com/en-us/training/modules/learn-continuous-integration-github-actions/

https://learn.microsoft.com/en-us/training/modules/github-actions-automate-tasks/

https://learn.microsoft.com/en-us/training/modules/github-actions-ci/

https://learn.microsoft.com/en-us/training/modules/github-actions-cd/

Bicep:

https://learn.microsoft.com/en-us/training/paths/fundamentals-bicep/

https://learn.microsoft.com/en-us/training/paths/bicep-github-actions/

Translated to Italian:

https://learn.microsoft.com/it-it/training/modules/github-actions-cd/

Bicep:

https://learn.microsoft.com/it-it/training/paths/fundamentals-bicep/

https://learn.microsoft.com/it-it/training/paths/bicep-github-actions/