Usare CI/CD di Azure Spring Apps con GitHub Actions

Nota

Azure Spring Apps è il nuovo nome del servizio Azure Spring Cloud. Anche se il servizio ha un nuovo nome, il nome precedente verrà visualizzato in alcune posizioni per un po' mentre si lavora per aggiornare gli asset, ad esempio screenshot, video e diagrammi.

Questo articolo si applica a: ✔️ Basic/Standard ✔️ Enterprise

Questo articolo illustra come creare un flusso di lavoro CI/CD per Azure Spring Apps con GitHub Actions.

GitHub Actions supporta un flusso di lavoro automatizzato del ciclo di vita dello sviluppo software. Con GitHub Actions per Azure Spring Apps è possibile creare flussi di lavoro nel repository per compilare, testare, creare pacchetti, rilasciare e distribuire in Azure.

Prerequisiti

Questo esempio richiede l'interfaccia della riga di comando di Azure.

Configurare il repository GitHub ed eseguire l'autenticazione

È necessaria una credenziale dell'entità servizio di Azure per autorizzare l'azione di accesso di Azure. Per ottenere credenziali di Azure, eseguire i comandi seguenti nel computer locale:

az login
az ad sp create-for-rbac \
    --role contributor \
    --scopes /subscriptions/<SUBSCRIPTION_ID> \
    --json-auth

Per accedere a un gruppo di risorse specifico, è possibile ridurre l'ambito:

az ad sp create-for-rbac \
    --role contributor \
    --scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP> \
    --json-auth

Il comando deve restituire un oggetto JSON:

{
    "clientId": "<GUID>",
    "clientSecret": "<GUID>",
    "subscriptionId": "<GUID>",
    "tenantId": "<GUID>",
    ...
}

Questo esempio usa l'esempio steeltoe in GitHub. Creare una copia tramite fork del repository, aprire la pagina del repository GitHub per il fork e selezionare la scheda Impostazioni. Aprire il menu Segreti e selezionare Nuovo segreto:

Screenshot of the GitHub Actions secrets and variables page with the New repository secret button highlighted.

Impostare il nome del segreto su AZURE_CREDENTIALS e il relativo valore sulla stringa JSON trovata sotto l'intestazione Configurare il repository GitHub ed eseguire l'autenticazione.

Screenshot of the GitHub Actions secrets / New secret page.

È anche possibile ottenere le credenziali di accesso di Azure da Key Vault in GitHub Actions, come illustrato in Autenticare Azure Spring con Key Vault in GitHub Actions.

Effettuare il provisioning dell'istanza del servizio

Per effettuare il provisioning dell'istanza del servizio Azure Spring Apps, eseguire i comandi seguenti usando l'interfaccia della riga di comando di Azure.

az extension add --name spring
az group create \
    --name <resource-group-name> \
    --location eastus 
az spring create \
    --resource-group <resource-group-name> \
    --name <service-instance-name> 
az spring config-server git set \
    --name <service-instance-name> \
    --uri https://github.com/Azure-Samples/azure-spring-apps-samples \
    --label main \
    --search-paths steeltoe-sample/config

Compilare il flusso di lavoro

Il flusso di lavoro viene definito usando le opzioni seguenti.

Preparare la distribuzione con l'interfaccia della riga di comando di Azure

Il comando az spring app create non è attualmente idempotente. Dopo l'esecuzione, viene visualizzato un errore se si esegue di nuovo lo stesso comando. È consigliabile usare questo flusso di lavoro in app e istanze di Azure Spring Apps esistenti.

Usare i comandi seguenti dell'interfaccia della riga di comando di Azure per la preparazione:

az config set defaults.group=<service-group-name>
az config set defaults.spring=<service-instance-name>
az spring app create --name planet-weather-provider
az spring app create --name solar-system-weather

Distribuire direttamente con l'interfaccia della riga di comando di Azure

Creare il file .github/workflows/main.yml nel repository con il contenuto seguente. Sostituire <il nome> del gruppo di risorse e <il nome> del servizio con i valori corretti.

name: Steeltoe-CD

# Controls when the action runs. Triggers the workflow on push or pull request
# events but only for the main branch
on:
  push:
    branches: [ main]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job runs on
    runs-on: ubuntu-latest
    env:
      working-directory: ./steeltoe-sample
      resource-group-name: <your resource group name>
      service-name: <your service name>

    # Supported .NET Core version matrix.
    strategy:
      matrix:
        dotnet: [ '3.1.x' ]

    # Steps represent a sequence of tasks that is executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Set up .NET Core 3.1 SDK
      - uses: actions/setup-dotnet@v1
        with:
          dotnet-version: ${{ matrix.dotnet }}

      # Set credential for az login
      - uses: azure/login@v1.1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: install Azure CLI extension
        run: |
          az extension add --name spring --yes

      - name: Build and package planet-weather-provider app
        working-directory: ${{env.working-directory}}/src/planet-weather-provider
        run: |
          dotnet publish
          az spring app deploy -n planet-weather-provider --runtime-version NetCore_31 --main-entry Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider.dll --artifact-path ./publish-deploy-planet.zip -s ${{ env.service-name }} -g ${{ env.resource-group-name }}
      - name: Build solar-system-weather app
        working-directory: ${{env.working-directory}}/src/solar-system-weather
        run: |
          dotnet publish
          az spring app deploy -n solar-system-weather --runtime-version NetCore_31 --main-entry Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather.dll --artifact-path ./publish-deploy-solar.zip -s ${{ env.service-name }} -g ${{ env.resource-group-name }}

Configurare il repository GitHub ed eseguire l'autenticazione

È necessaria una credenziale dell'entità servizio di Azure per autorizzare l'azione di accesso di Azure. Per ottenere credenziali di Azure, eseguire i comandi seguenti nel computer locale:

az login
az ad sp create-for-rbac \
    --role contributor \
    --scopes /subscriptions/<SUBSCRIPTION_ID> \
    --json-auth

Per accedere a un gruppo di risorse specifico, è possibile ridurre l'ambito:

az ad sp create-for-rbac \
    --role contributor \
    --scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP> \
    --json-auth

Il comando deve restituire un oggetto JSON:

{
    "clientId": "<GUID>",
    "clientSecret": "<GUID>",
    "subscriptionId": "<GUID>",
    "tenantId": "<GUID>",
    ...
}

Questo esempio usa l'esempio PiggyMetrics in GitHub. Creare una copia tramite fork dell'esempio, deselezionare Copia solo il ramo di Azure, aprire la pagina del repository GitHub e selezionare la scheda Impostazioni. Aprire il menu Segreti e selezionare Aggiungi un nuovo segreto:

Screenshot of the GitHub Actions secrets and variables page with the New repository secret button highlighted.

Impostare il nome del segreto su AZURE_CREDENTIALS e il relativo valore sulla stringa JSON trovata sotto l'intestazione Configurare il repository GitHub ed eseguire l'autenticazione.

Screenshot of the GitHub Actions secrets / New secret page.

È anche possibile ottenere le credenziali di accesso di Azure da Key Vault in GitHub Actions, come illustrato in Autenticare Azure Spring con Key Vault in GitHub Actions.

Effettuare il provisioning dell'istanza del servizio

Per effettuare il provisioning dell'istanza del servizio Azure Spring Apps, eseguire i comandi seguenti usando l'interfaccia della riga di comando di Azure.

az extension add --name spring
az group create --location eastus --name <resource group name>
az spring create -n <service instance name> -g <resource group name>
az spring config-server git set -n <service instance name> --uri https://github.com/xxx/piggymetrics --label config

Flussi di lavoro di esempio end-to-end

Gli esempi seguenti illustrano scenari di utilizzo comuni.

Distribuzione

Le sezioni seguenti illustrano varie opzioni per la distribuzione dell'app.

In produzione

Azure Spring Apps supporta la distribuzione nelle distribuzioni con artefatti compilati (ad esempio JAR o .NET Core ZIP) o archivio del codice sorgente.

L'esempio seguente viene distribuito nella distribuzione di produzione predefinita in Azure Spring Apps usando il file JAR compilato da Maven. Questo esempio è l'unico scenario di distribuzione possibile quando si usa lo SKU Basic:

Nota

Il modello di ricerca del pacchetto deve restituire solo un pacchetto. Se l'attività di compilazione produce più pacchetti JAR, ad esempio sources.jar e javadoc.jar, è necessario perfezionare il modello di ricerca in modo che corrisponda solo all'artefatto binario dell'applicazione.

name: AzureSpringApps
on: push
env:
  ASC_PACKAGE_PATH: ${{ github.workspace }}
  AZURE_SUBSCRIPTION: <azure subscription name>

jobs:
  deploy_to_production:
    runs-on: ubuntu-latest
    name: deploy to production with artifact
    steps:
      - name: Checkout GitHub Action
        uses: actions/checkout@v2

      - name: Set up Java 11
        uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: '11'

      - name: maven build, clean
        run: |
          mvn clean package

      - name: Login via Azure CLI
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: deploy to production with artifact
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: Deploy
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: false
          package: ${{ env.ASC_PACKAGE_PATH }}/**/*.jar

L'esempio seguente viene distribuito nella distribuzione di produzione predefinita in Azure Spring Apps usando il codice sorgente.

name: AzureSpringApps
on: push
env:
  ASC_PACKAGE_PATH: ${{ github.workspace }}
  AZURE_SUBSCRIPTION: <azure subscription name>

jobs:
  deploy_to_production:
    runs-on: ubuntu-latest
    name: deploy to production with source code
    steps:
      - name: Checkout GitHub Action
        uses: actions/checkout@v2

      - name: Login via Azure CLI
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: deploy to production step with source code
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: false
          package: ${{ env.ASC_PACKAGE_PATH }}

L'esempio seguente viene distribuito nella distribuzione di produzione predefinita in Azure Spring Apps usando il codice sorgente nel piano Enterprise. È possibile specificare il generatore da usare per le azioni di distribuzione usando l'opzione builder .

name: AzureSpringApps
on: push
env:
  ASC_PACKAGE_PATH: ${{ github.workspace }}
  AZURE_SUBSCRIPTION: <azure subscription name>

jobs:
  deploy_to_production:
    runs-on: ubuntu-latest
    name: deploy to production with source code
    steps:
      - name: Checkout GitHub Action
        uses: actions/checkout@v2

      - name: Login via Azure CLI
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: deploy to production step with source code in the Enterprise plan
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: false
          package: ${{ env.ASC_PACKAGE_PATH }}
          builder: <builder>

L'esempio seguente viene distribuito nella distribuzione di produzione predefinita in Azure Spring Apps con un'immagine del contenitore esistente.

name: AzureSpringApps
on: push
env:
  ASC_PACKAGE_PATH: ${{ github.workspace }}
  AZURE_SUBSCRIPTION: <azure subscription name>

jobs:
  deploy_to_production:
    runs-on: ubuntu-latest
    name: deploy to production with source code
    steps:
      - name: Checkout GitHub Action
        uses: actions/checkout@v2

      - name: Login via Azure CLI
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Deploy Custom Image
        uses: Azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          deployment-name: <deployment name>
          container-registry: <your container image registry>
          registry-username: ${{ env.REGISTRY_USERNAME }}
          registry-password: ${{ secrets.REGISTRY_PASSWORD }}
          container-image: <your image tag>

Durante la distribuzione, è possibile ottenere più funzionalità usando più argomenti. Per altre informazioni, vedere la sezione Argomenti di GitHub Action per la distribuzione in App Azure Spring.

Blu-verde

Gli esempi seguenti vengono distribuiti in una distribuzione di staging esistente. Questa distribuzione non riceve traffico di produzione finché non viene impostata come distribuzione di produzione. È possibile impostare use-staging-deployment true per trovare la distribuzione di staging automaticamente o semplicemente allocare un nome di distribuzione specifico. Ci concentriamo solo sull'azione spring-apps-deploy e lasciamo fuori i lavori preliminari nel resto dell'articolo.

# environment preparation configurations omitted
    steps:
      - name: blue green deploy step use-staging-deployment
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: true
          package: ${{ env.ASC_PACKAGE_PATH }}/**/*.jar
# environment preparation configurations omitted
    steps:
      - name: blue green deploy step with deployment-name
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          deployment-name: staging
          package: ${{ env.ASC_PACKAGE_PATH }}/**/*.jar

Per altre informazioni sulle distribuzioni blu-verde, incluso un approccio alternativo, vedere Strategie di distribuzione blu-verde.

Impostazione della distribuzione di produzione

Nell'esempio seguente la distribuzione di staging corrente viene impostata come produzione, scambiando in modo efficace la distribuzione che riceve il traffico di produzione.

# environment preparation configurations omitted
    steps:
      - name: set production deployment step
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: set-production
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: true

Eliminazione di una distribuzione di staging

L'azione Delete Staging Deployment consente di eliminare la distribuzione che non riceve traffico di produzione. Questa eliminazione libera le risorse usate da tale distribuzione e rende spazio per una nuova distribuzione di staging:

# environment preparation configurations omitted
    steps:
      - name: Delete staging deployment step
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: delete-staging-deployment
          service-name: <service instance name>
          app-name: <app name>

Creare o aggiornare la compilazione (solo piano Enterprise)

L'esempio seguente crea o aggiorna una risorsa di compilazione nel piano Enterprise:

# environment preparation configurations omitted
    steps:
      - name: Create or update build
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: build
          service-name: <service instance name>
          build-name: <build name>
          package: ${{ env.ASC_PACKAGE_PATH }}
          builder: <builder>

Elimina compilazione (solo piano enterprise)

Nell'esempio seguente viene eliminata una risorsa di compilazione nel piano Enterprise:

# environment preparation configurations omitted
    steps:
      - name: Delete build
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: delete-build
          service-name: <service instance name>
          build-name: <build name>

Distribuire con il plug-in Maven

Un'altra opzione consiste nell'usare il plug-in Maven per distribuire il file Jar e aggiornare le impostazioni dell'app. Il comando mvn azure-spring-apps:deploy è idempotente e crea automaticamente le app, se necessario. Non è necessario creare in anticipo le app corrispondenti.

name: AzureSpringApps
on: push

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:

    - uses: actions/checkout@main

    - name: Set up Java 11
      uses: actions/setup-java@v3
      with:
        distribution: 'temurin'
        java-version: '11'

    - name: maven build, clean
      run: |
        mvn clean package -DskipTests

    # Maven plugin can cosume this authentication method automatically
    - name: Azure Login
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

    # Maven deploy, make sure you have correct configurations in your pom.xml
    - name: deploy to Azure Spring Apps using Maven
      run: |
        mvn azure-spring-apps:deploy

Eseguire il flusso di lavoro

GitHub Actions deve essere abilitato automaticamente dopo il push di .github/workflow/main.yml in GitHub. L'azione viene attivata quando si esegue il push di un nuovo commit. Se si crea questo file nel browser, l'azione dovrebbe essere già stata eseguita.

Per verificare che l'azione sia stata abilitata, selezionare la scheda Azioni nella pagina del repository GitHub:

Screenshot of the GitHub Actions tab showing the All workflows section.

Se l'azione viene eseguita in caso di errore, ad esempio, se non è stata impostata la credenziale di Azure, è possibile rieseguire i controlli dopo aver risolto l'errore. Nella pagina del repository GitHub selezionare Azioni, selezionare l'attività del flusso di lavoro specifica e quindi selezionare il pulsante Riesegui controlli per rieseguire i controlli :

Screenshot of the GitHub Actions tab with the Re-run checks button highlighted.

Passaggi successivi