Kafka: GitHub Actions & GitLab CI

Avvia un vero servizio Kafka dalla tua pipeline GitHub Actions o GitLab CI, esegui i tuoi test su di esso e rimuovilo automaticamente

👋 Benvenuti nella documentazione di Stackhero!

Stackhero semplifica l'avvio di una soluzione Kafka cloud completamente gestita. Ecco cosa potete aspettarvi:

  • Dimensioni e trasferimenti dei messaggi illimitati per supportare la crescita dei vostri dati.
  • Aggiornamenti senza sforzo, applicate le ultime novità con un solo clic.
  • Prestazioni di alto livello e sicurezza avanzata, tutto alimentato dalla vostra VM privata e dedicata.

Se desiderate risparmiare tempo e ottimizzare il vostro workflow, vi consigliamo di provare il servizio di hosting Kafka cloud di Stackhero. Bastano circa 5 minuti per essere operativi!

Questa guida ti accompagnerà nell'esecuzione di un servizio Kafka reale e dedicato all'interno della tua pipeline CI utilizzando GitHub Actions o GitLab CI. Seguendo questi passaggi, potrai testare il tuo codice su un'istanza Kafka attiva in condizioni simili a quelle di produzione, senza dover ricorrere a mock o simulazioni. Apache Kafka is a distributed event streaming platform built to carry huge streams of events through your systems in real time.

Ad ogni esecuzione della pipeline, verrà creata una nuova istanza Kafka. In questo modo, i tuoi test interagiranno con lo stesso tipo di servizio che i tuoi utenti vedranno in produzione. Il workflow crea automaticamente uno stack temporaneo, aggiunge Kafka, attende che sia pronto, recupera le credenziali generate, esegue uno smoke test tramite netcat (a TCP check) e, al termine, esegue sempre la pulizia di tutte le risorse.

Utilizzerai il Stackhero CLI, uno strumento da riga di comando standalone che rende il lancio e la gestione dei servizi Stackhero semplice e veloce.

Per consentire al CLI di funzionare in modalità non interattiva, avrai bisogno di un access token (formato: usr-xxxxxx:tokenId). È sufficiente creare questo token una sola volta e poi aggiungerlo alla pipeline CI come secret sicuro e cifrato.

  1. Crea il token: Nel tuo dashboard Stackhero, clicca sulla tua immagine profilo in alto a destra, vai su Il tuo account, poi su Access tokens e clicca su Crea token.
  2. Per GitHub Actions: Nel tuo repository, vai su Settings > Secrets and variables > Actions > New repository secret e inserisci il token come STACKHERO_TOKEN.
  3. Per GitLab CI: Nel tuo progetto, vai su Settings > CI/CD > Variables > Add variable, imposta la chiave su STACKHERO_TOKEN e seleziona Masked (e Protected se la tua CI viene eseguita solo su branch protetti).

Non inserire mai il tuo access token direttamente nel file YAML della pipeline. Se presente nel YAML, potrebbe essere esposto a chiunque abbia accesso al repository e potrebbe comparire nei log di build. Salvarlo come secret CI garantisce che rimanga cifrato e mascherato, mantenendo il token sicuro.

Ecco un esempio completo di script che gestisce l'intero ciclo di vita del servizio. Dimostra quanto sia semplice la configurazione, con pochi comandi. Puoi copiare il file YAML già pronto per la tua piattaforma dalle sezioni sottostanti.

#!/bin/bash
set -euo pipefail

# STACKHERO_TOKEN viene fornito dal secret CI, il CLI lo rileva automaticamente.

stackName="ci-kafka-$$"          # Nome stack univoco per ogni esecuzione
serviceStore="kafka"             # Il service store di Kafka
instance="10G"        # Modifica se necessario (vedi step 3)
region="europe"                         # Nome regione (vedi stackhero regions-list)

# 1. Installa il CLI sul runner
curl -fsSL https://www.stackhero.io/install.sh | sh

# 2. Installa il client necessario per lo smoke test (jq + curl sono la base)
apt-get update && apt-get install -y --no-install-recommends jq curl netcat-openbsd

# 3. Crea uno stack dedicato per questa esecuzione
stackId=$(stackhero --format=script stack-create --name="$stackName")
echo "Stack creato: $stackId"

# 4. Aggiungi Kafka e ottieni il suo service id
serviceId=$(stackhero --format=script service-add \
  --stack="$stackId" \
  --service-store="$serviceStore" \
  --instance="$instance" \
  --region="$region")
echo "Servizio aggiunto: $serviceId"

# 5. Attendi che il servizio sia operativo (può richiedere alcuni minuti)
stackhero service-wait-for --service="$serviceId"

# 6. Leggi la configurazione (contiene le credenziali generate)
config=$(stackhero service-configuration-get --service="$serviceId" --format=json)

# 7. Estrai le credenziali necessarie
host=$(echo "$config" | jq -r '.configuration.domain')

# 8. Smoke test: Open a TCP connection to the broker port.
nc -z -w 5 "$host" 9092

echo "✅ Kafka è raggiungibile dalla CI."

La fase di teardown, che elimina il servizio, attende la sua rimozione e poi elimina lo stack, viene gestita nelle sezioni specifiche per ciascuna piattaforma qui sotto. Questo approccio garantisce che la pulizia venga sempre eseguita, anche se uno smoke test fallisce.

Uno stack può essere eliminato solo quando è vuoto. Elimina sempre prima il servizio e attendi la sua rimozione, poi elimina lo stack. Il comando service-wait-for assicura che il servizio sia in esecuzione o eliminato prima di procedere, rendendolo lo strumento ideale anche per attendere la cancellazione.

Gli esempi qui sotto utilizzano di default l'istanza entry-level 10G per Kafka. È una scelta solida per la maggior parte dei carichi di lavoro, ma puoi modificarla secondo le tue esigenze. Per visualizzare tutte le tipologie di istanza disponibili per Kafka, puoi eseguire:

# La colonna NAME mostra il valore da passare a --instance
stackhero instances-store-list --service-store=kafka

Per iniziare, puoi salvare il seguente contenuto come .github/workflows/ci.yml. Da questo momento, ogni push e pull request eseguirà i test su una vera istanza Kafka.

name: CI con Kafka

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      STACKHERO_TOKEN: ${{ secrets.STACKHERO_TOKEN }}
      STACK_NAME: ci-kafka-${{ github.run_id }}-${{ github.run_attempt }}
      INSTANCE: "10G"   # Modifica se necessario (vedi step 3)
      REGION: europe
    steps:
      - uses: actions/checkout@v4

      - name: Installa Stackhero CLI e il client
        run: |
          curl -fsSL https://www.stackhero.io/install.sh | sh
          apt-get update && apt-get install -y --no-install-recommends jq curl netcat-openbsd

      - name: Crea il servizio Kafka
        run: |
          set -euo pipefail
          STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
          echo "STACK_ID=$STACK_ID" >> "$GITHUB_ENV"
          SERVICE_ID=$(stackhero --format=script service-add \
            --stack="$STACK_ID" \
            --service-store="kafka" \
            --instance="$INSTANCE" \
            --region="$REGION")
          echo "SERVICE_ID=$SERVICE_ID" >> "$GITHUB_ENV"
          stackhero service-wait-for --service="$SERVICE_ID"

      - name: Esegui i test su Kafka
        run: |
          set -euo pipefail
          config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
          host=$(echo "$config" | jq -r '.configuration.domain')
          # Open a TCP connection to the broker port.
          nc -z -w 5 "$host" 9092
          echo "✅ Kafka è raggiungibile dalla CI."
          # Puoi eseguire la tua suite di test qui utilizzando le credenziali sopra ...

      - name: Teardown (sempre, anche in caso di errore)
        if: always()
        run: |
          if [ -n "${SERVICE_ID:-}" ]; then
            stackhero service-delete --service="$SERVICE_ID" --confirm
            stackhero service-wait-for --service="$SERVICE_ID"
          fi
          if [ -n "${STACK_ID:-}" ]; then
            stackhero stack-delete --stack="$STACK_ID" --confirm
          fi

La fase di teardown è configurata con if: always() così da essere sempre eseguita, garantendo che la tua istanza Kafka venga eliminata e che non vengano addebitate risorse inutilizzate.

Puoi salvare questa configurazione come .gitlab-ci.yml. Con questa impostazione, ogni esecuzione della pipeline avvierà una nuova istanza reale di Kafka per i tuoi test.

test:
  image: ubuntu:24.04
  variables:
    STACK_NAME: "ci-kafka-$CI_PIPELINE_ID-$CI_JOB_ID"
    INSTANCE: "10G"   # Modifica se necessario (vedi step 3)
    REGION: "europe"
    SERVICE_STORE: "kafka"
  # STACKHERO_TOKEN proviene dalla variabile CI/CD creata allo step 1.
  script:
    - set -euo pipefail
    - curl -fsSL https://www.stackhero.io/install.sh | sh
    - apt-get update && apt-get install -y --no-install-recommends jq curl netcat-openbsd
    - STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
    - echo "STACK_ID=$STACK_ID" >> deploy.env
    - SERVICE_ID=$(stackhero --format=script service-add --stack="$STACK_ID" --service-store="$SERVICE_STORE" --instance="$INSTANCE" --region="$REGION")
    - echo "SERVICE_ID=$SERVICE_ID" >> deploy.env
    - stackhero service-wait-for --service="$SERVICE_ID"
    - config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
    - host=$(echo "$config" | jq -r '.configuration.domain')
    # Open a TCP connection to the broker port.
    - nc -z -w 5 "$host" 9092
    - echo "✅ Kafka è raggiungibile dalla CI."
    # Puoi eseguire la tua suite di test qui utilizzando le credenziali sopra ...
  after_script:
    - test -f deploy.env && . ./deploy.env || true
    - >
      if [ -n "${SERVICE_ID:-}" ]; then
        stackhero service-delete --service="$SERVICE_ID" --confirm
        stackhero service-wait-for --service="$SERVICE_ID"
      fi
    - >
      if [ -n "${STACK_ID:-}" ]; then
        stackhero stack-delete --stack="$STACK_ID" --confirm
      fi

In GitLab, la pulizia avviene nella sezione after_script. Questa parte viene sempre eseguita, anche in caso di errore del job, così le risorse Kafka vengono eliminate e non ti vengono addebitate risorse non utilizzate.

In GitLab, after_script viene eseguito in una shell pulita. Per gestire questa situazione, lo script salva gli ID di servizio e stack in deploy.env durante il job e li ricarica prima della pulizia. In questo modo, anche in caso di errore durante il job, le tue risorse vengono comunque eliminate.

Questo è l'intero ciclo CI per Kafka: crea uno stack, aggiungi il servizio, attendi, recupera le credenziali, smoke test e sempre teardown. Ogni esecuzione della pipeline ottiene un servizio reale e isolato, senza lasciare nulla in esecuzione al termine. Per ulteriori informazioni sui comandi disponibili e sull'autenticazione non interattiva tramite STACKHERO_TOKEN, puoi consultare la documentazione CLI completa.