Come si usa GitHub Actions per eseguire la distribuzione in Azure?

Completato

In questa unità viene illustrato come usare GitHub Actions per distribuire un'app Web basata su contenitori in app Web di Microsoft Azure. Vengono illustrate alcune opzioni per l'attivazione di un flusso di lavoro. Viene quindi illustrato come si usano le istruzioni condizionali nel flusso di lavoro. Infine, verrà spiegato come creare ed eliminare le risorse di Azure usando GitHub Actions.

Opzioni per l'attivazione di un flusso di lavoro di distribuzione continua

Sono disponibili diverse opzioni per l'avvio di un flusso di lavoro di distribuzione continua. Nel modulo precedente su CI con GitHub Actions si è appreso come attivare un flusso di lavoro da un push nel repository GitHub. Tuttavia, per la distribuzione continua, potrebbe essere necessario attivare un flusso di lavoro di distribuzione per un altro evento.

Un'opzione consiste nell'attivare il flusso di lavoro con ChatOps. ChatOps usa client chat, chatbot e strumenti per la comunicazione in tempo reale per eseguire le attività. Ad esempio, è possibile lasciare un commento specifico in una richiesta pull che può avviare un bot. Tale bot potrebbe lasciare a sua volta un commento con alcune statistiche o eseguire un flusso di lavoro.

Un'altra opzione, quella usata nell'esempio, consiste nell'usare etichette nella richiesta pull. Etichette diverse possono avviare flussi di lavoro diversi. Ad esempio, aggiungere un'etichetta fase per avviare un flusso di lavoro di distribuzione nell'ambiente di gestione temporanea. In alternativa, aggiungere un'etichetta ambiente di spin up per eseguire il flusso di lavoro che crea le risorse di Microsoft Azure in cui eseguire la distribuzione. Per usare le etichette, il flusso di lavoro è simile al seguente:

on:
  pull_request:
    types: [labeled]

Controllare l'esecuzione con un processo condizionale

Spesso si decide di eseguire un flusso di lavoro solo se si verifica una condizione.

I flussi di lavoro di GitHub offrono l'istruzione condizionale if per questo scenario. L'istruzione condizionale usa un'espressione che viene valutata in fase di esecuzione. Ad esempio, si vuole eseguire questo flusso di lavoro se viene aggiunta l'etichetta stage (fase) alla richiesta pull.

if: contains(github.event.pull_request.labels.*.name, 'stage')

Archiviare le credenziali con i segreti di GitHub

Non è opportuno esporre informazioni riservate nel file del flusso di lavoro. I segreti di GitHub sono un posto sicuro in cui archiviare le informazioni riservate necessarie per il flusso di lavoro. Ecco un esempio.

Per eseguire la distribuzione in una risorsa di Azure, GitHub Actions deve avere l'autorizzazione necessaria per accedere alla risorsa. Non è consigliabile archiviare le credenziali di Azure nel file del flusso di lavoro in cui sono visibili a tutti. Le credenziali possono invece essere archiviate nei segreti di GitHub.

Per archiviare informazioni nei segreti di GitHub, creare un segreto nel portale.

Interfaccia del portale di Azure per la creazione di un segreto.

Usare quindi il nome del segreto creato nel flusso di lavoro in cui è necessario avere a disposizione tali informazioni. Ad esempio, usare le credenziali di Azure archiviate nei segreti di GitHub nell'attributo creds: di un'azione login di Azure.

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

Eseguire la distribuzione in Microsoft Azure usando GitHub Actions

Il marketplace GitHub include diverse azioni che consentono di automatizzare le attività correlate ad Azure.

Marketplace GitHub con i risultati della ricerca per Azure.

È inoltre possibile cercare e sfogliare GitHub Actions direttamente nell'editor di flussi di lavoro di un repository. Dalla barra laterale è possibile cercare un'azione specifica, visualizzare le azioni in primo piano ed esplorare le categorie in primo piano.

Per trovare un'azione:

  1. Nel repository individuare il file del flusso di lavoro che si desidera modificare.
  2. Selezionare l'icona Modifica nell'angolo in alto a destra della vista file.
  3. Usare la barra laterale del marketplace GitHub a destra dell'editor per esplorare le azioni.

Si supponga di voler distribuire un'app Web basata su contenitori in app Web di Azure. Se si esegue una ricerca nel marketplace GitHub, vengono rilevate queste azioni:

Se si aggiungono queste azioni al processo Deploy-to-Azure, il flusso di lavoro sarà simile al seguente:

  Deploy-to-Azure:
    runs-on: ubuntu-latest
    needs: Build-Docker-Image
    name: Deploy app container to Azure
    steps:
      - name: "Login via Azure CLI"
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - uses: azure/docker-login@v1
        with:
          login-server: ${{env.IMAGE_REGISTRY_URL}}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Deploy web app container
        uses: azure/webapps-deploy@v1
        with:
          app-name: ${{env.AZURE_WEBAPP_NAME}}
          images: ${{env.IMAGE_REGISTRY_URL}}/${{ github.repository }}/${{env.DOCKER_IMAGE_NAME}}:${{ github.sha }}

      - name: Azure logout
        run: |
          az logout

Si noti che questo processo dipende da un processo precedente, Build-Docker-Image. Il processo precedente crea l'artefatto che viene distribuito.

L'azione azure/login@v1 richiede le credenziali per accedere all'account di Azure in modo che sia possibile accedere alle risorse di Azure in cui si vuole eseguire la distribuzione. Qui vengono usate le credenziali archiviate nei segreti di GitHub.

Lo stesso vale per l'azione azure/docker-login@v1. Poiché si sta distribuendo un'immagine del contenitore, è necessario accedere al registro contenitori privato.

L'azione azure/webapps-deploy@v1 esegue la distribuzione. Dipende dalle due azioni precedenti.

Creare ed eliminare le risorse di Azure usando GitHub Actions

Poiché la distribuzione continua è un processo automatizzato, si è già deciso di usare l'infrastruttura come codice per creare e disinstallare gli ambienti in cui viene eseguita la distribuzione. GitHub Actions è in grado di automatizzare queste attività in Azure ed è possibile includere le relative azioni nel flusso di lavoro.

Nota

Tenere presente che è importante disinstallare le risorse non più necessarie il prima possibile per evitare addebiti superflui.

Un'opzione è creare un nuovo flusso di lavoro con due processi, uno che avvia le risorse e uno che le elimina. Quindi, usare un'istruzione condizionale per eseguire solo un processo. In questo esempio l'istruzione condizionale cerca un'etichetta nella richiesta pull ed esegue il processo set-up-azure-resources se l'etichetta è spin up environment (ambiente di avvio) e il processo destroy-azure-resources se l'etichetta è destroy environment (ambiente di eliminazione definitiva).

jobs:
  set-up-azure-resources:
    runs-on: ubuntu-latest

    if: contains(github.event.pull_request.labels.*.name, 'spin up environment')

    ...

  destroy-azure-resources:
    runs-on: ubuntu-latest

    if: contains(github.event.pull_request.labels.*.name, 'destroy environment')

    ...

I processi usano l'interfaccia della riga di comando di Azure per creare ed eliminare definitivamente le risorse di Azure. Per altre informazioni sull'interfaccia della riga di comando di Azure, vedere Panoramica dell'interfaccia della riga di comando di Azure.

Di seguito è riportato un esempio dei passaggi del processo set-up-azure-resources:

steps:
  - name: Checkout repository
    uses: actions/checkout@v2

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

  - name: Create Azure resource group
    if: success()
    run: |
      az group create --location ${{env.AZURE_LOCATION}} --name ${{env.AZURE_RESOURCE_GROUP}} --subscription ${{secrets.AZURE_SUBSCRIPTION_ID}}
  - name: Create Azure app service plan
    if: success()
    run: |
      az appservice plan create --resource-group ${{env.AZURE_RESOURCE_GROUP}} --name ${{env.AZURE_APP_PLAN}} --is-linux --sku F1 --subscription ${{secrets.AZURE_SUBSCRIPTION_ID}}
  - name: Create webapp resource
    if: success()
    run: |
      az webapp create --resource-group ${{ env.AZURE_RESOURCE_GROUP }} --plan ${{ env.AZURE_APP_PLAN }} --name ${{ env.AZURE_WEBAPP_NAME }}  --deployment-container-image-name nginx --subscription ${{secrets.AZURE_SUBSCRIPTION_ID}}
  - name: Configure webapp to use GitHub Packages
    if: success()
    run: |
      az webapp config container set --docker-custom-image-name nginx --docker-registry-server-password ${{secrets.GITHUB_TOKEN}} --docker-registry-server-url https://docker.pkg.github.com --docker-registry-server-user ${{github.actor}} --name ${{ env.AZURE_WEBAPP_NAME }} --resource-group ${{ env.AZURE_RESOURCE_GROUP }} --subscription ${{secrets.AZURE_SUBSCRIPTION_ID}}

Si noti che si usa GitHub Actions per estrarre il repository e per accedere ad Azure. Successivamente, si creano le risorse necessarie e si distribuisce il contenitore usando l'interfaccia della riga di comando di Azure.