Esercitazione: Creare una pipeline a più fasi con Azure DevOps

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

È possibile usare una pipeline multistage di Azure DevOps per dividere il processo CI/CD in fasi che rappresentano parti diverse del ciclo di sviluppo. L'uso di una pipeline a più fasi offre maggiore visibilità sul processo di distribuzione e semplifica l'integrazione delle approvazioni e dei controlli.

In questo articolo si creeranno due istanze servizio app e si creerà una pipeline YAML con tre fasi:

In uno scenario reale, potrebbe essere disponibile un'altra fase per la distribuzione nell'ambiente di produzione a seconda del processo DevOps.

Il codice di esempio in questo esercizio è destinato a un'applicazione Web .NET per un gioco di spazio fittizio che include un tabellone punteggi elevati. Si distribuirà sia nelle istanze di sviluppo che di gestione temporanea di App Web di Azure per Linux.

Prerequisiti

Creare una copia tramite fork del progetto

Creare una copia tramite fork del repository di esempio seguente in GitHub.

https://github.com/MicrosoftDocs/mslearn-tailspin-spacegame-web-deploy

Creare le istanze del servizio app

Prima di poter distribuire la pipeline, è necessario creare un'istanza di servizio app in cui eseguire la distribuzione. Per creare l'istanza si userà l'interfaccia della riga di comando di Azure.

  1. Accedere al portale di Azure.

  2. Dal menu selezionare Cloud Shell e l'esperienza Bash .

  3. Generare un numero casuale che renda univoco il nome di dominio dell'app Web. Il vantaggio di avere un valore univoco è che l'istanza di servizio app non avrà un conflitto di nomi con altri studenti che completano questa esercitazione.

    webappsuffix=$RANDOM    
    
  4. Aprire un prompt dei comandi e usare un az group create comando per creare un gruppo di risorse denominato tailspin-space-game-rg che contiene tutte le istanze di servizio app. Aggiornare il location valore per usare l'area più vicina.

    az group create --location eastus --name tailspin-space-game-rg
    
  5. Usare il prompt dei comandi per creare un piano di servizio app.

    az appservice plan create \
      --name tailspin-space-game-asp \
      --resource-group tailspin-space-game-rg \
      --sku B1 \
      --is-linux
    
  6. Nel prompt dei comandi creare due istanze servizio app, una per ogni istanza (Sviluppo e gestione temporanea) con il az webapp create comando .

    az webapp create \
      --name tailspin-space-game-web-dev-$webappsuffix \
      --resource-group tailspin-space-game-rg \
      --plan tailspin-space-game-asp \
      --runtime "DOTNET|6.0"
    
    az webapp create \
      --name tailspin-space-game-web-staging-$webappsuffix \
      --resource-group tailspin-space-game-rg \
      --plan tailspin-space-game-asp \
      --runtime "DOTNET|6.0"
    
  7. Con il prompt dei comandi elencare entrambe le istanze di servizio app per verificare che siano in esecuzione con il az webapp list comando .

    az webapp list \
      --resource-group tailspin-space-game-rg \
      --query "[].{hostName: defaultHostName, state: state}" \
      --output table
    
  8. Copiare i nomi delle istanze di servizio app da usare come variabili nella sezione successiva.

Creare il progetto e le variabili di Azure DevOps

Configurare il progetto Azure DevOps e una pipeline di compilazione. Si aggiungeranno anche variabili per le istanze di sviluppo e gestione temporanea.

La pipeline di compilazione:

  • Include un trigger che viene eseguito quando è presente una modifica del codice al ramo
  • Definisce due variabili e buildConfigurationreleaseBranchName
  • Include una fase denominata Build che compila l'applicazione Web
  • Pubblica un artefatto che verrà usato in una fase successiva

Aggiungere la fase di compilazione

  1. Accedere all'organizzazione di Azure DevOps e passare al progetto.

  2. Passare a Pipeline e quindi selezionare Nuova pipeline o Crea pipeline se si crea la prima pipeline.

  3. Eseguire i passaggi della procedura guidata selezionando prima di tutto GitHub come posizione del codice sorgente.

  4. Si potrebbe essere reindirizzati a GitHub per l'accesso. In questo caso, immettere le credenziali di GitHub.

  5. Quando si vede l’elenco dei repository, selezionarne uno.

  6. È possibile che si venga reindirizzati a GitHub per installare l'app Azure Pipelines. In tal caso, selezionare Approva e installa.

  1. Quando viene visualizzata la scheda Configura , selezionare Starter pipeline (Pipeline di avvio).

  2. Sostituire il contenuto di azure-pipelines.yml con questo codice.

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
      releaseBranchName: 'release'
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs: 
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-20.04'
          demands:
          - npm
    
        variables:
          wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
          dotnetSdkVersion: '6.x'
    
        steps:
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
    
        - task: Npm@1
          displayName: 'Run npm install'
          inputs:
            verbose: false
    
        - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
          displayName: 'Compile Sass assets'
    
        - task: gulp@1
          displayName: 'Run gulp tasks'
    
        - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
          displayName: 'Write build info'
          workingDirectory: $(wwwrootDir)
    
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
  3. Quando si è pronti, selezionare Salva ed esegui.

Aggiungere variabili di istanza

  1. In Azure DevOps passare a Libreria pipeline>.

  2. Selezionare + Gruppo di variabili.

  3. In Proprietà aggiungere Release per il nome del gruppo di variabili.

  4. Creare due variabili per fare riferimento ai nomi host di sviluppo e gestione temporanea. Sostituire il valore 1234 con il valore corretto per l'istanza.

    Nome variabile Valore di esempio
    WebAppNameDev tailspin-space-game-web-dev-1234
    WebAppNameStaging tailspin-space-game-web-staging-1234
  5. Selezionare Salva per salvare le variabili.

Aggiungere la fase di sviluppo

Si aggiornerà quindi la pipeline per alzare di livello la compilazione alla fase di sviluppo .

  1. In Azure Pipelines passare a Pipelines.In Azure Pipelines (Pipeline di> pipeline).

  2. Selezionare Modifica nel menu contestuale per modificare la pipeline.

    Screenshot della voce di menu Modifica.

  3. Aggiornare azure-pipelines.yml per includere una fase di sviluppo. Nella fase sviluppo la pipeline:

    • Eseguire quando la fase di compilazione ha esito positivo a causa di una condizione

    • Scaricare un artefatto da drop

    • Eseguire la distribuzione nel servizio app Azure con una connessione al servizio Azure Resource Manager

      trigger:
      - '*'
      
      variables:
        buildConfiguration: 'Release'
        releaseBranchName: 'release'
      
      stages:
      - stage: 'Build'
        displayName: 'Build the web application'
        jobs: 
        - job: 'Build'
          displayName: 'Build job'
          pool:
            vmImage: 'ubuntu-20.04'
            demands:
            - npm
      
          variables:
            wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
            dotnetSdkVersion: '6.x'
      
          steps:
          - task: UseDotNet@2
            displayName: 'Use .NET SDK $(dotnetSdkVersion)'
            inputs:
              version: '$(dotnetSdkVersion)'
      
          - task: Npm@1
            displayName: 'Run npm install'
            inputs:
              verbose: false
      
          - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
            displayName: 'Compile Sass assets'
      
          - task: gulp@1
            displayName: 'Run gulp tasks'
      
          - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
            displayName: 'Write build info'
            workingDirectory: $(wwwrootDir)
      
          - task: DotNetCoreCLI@2
            displayName: 'Restore project dependencies'
            inputs:
              command: 'restore'
              projects: '**/*.csproj'
      
          - task: DotNetCoreCLI@2
            displayName: 'Build the project - $(buildConfiguration)'
            inputs:
              command: 'build'
              arguments: '--no-restore --configuration $(buildConfiguration)'
              projects: '**/*.csproj'
      
          - task: DotNetCoreCLI@2
            displayName: 'Publish the project - $(buildConfiguration)'
            inputs:
              command: 'publish'
              projects: '**/*.csproj'
              publishWebProjects: false
              arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
              zipAfterPublish: true
      
          - publish: '$(Build.ArtifactStagingDirectory)'
            artifact: drop
      
      - stage: 'Dev'
        displayName: 'Deploy to the dev environment'
        dependsOn: Build
        condition:  succeeded()
        jobs:
        - deployment: Deploy
          pool:
            vmImage: 'ubuntu-20.04'
          environment: dev
          variables:
          - group: Release
          strategy:
            runOnce:
              deploy:
                steps:
                - download: current
                  artifact: drop
                - task: AzureWebApp@1
                  displayName: 'Azure App Service Deploy: website'
                  inputs:
                    azureSubscription: 'your-subscription'
                    appType: 'webAppLinux'
                    appName: '$(WebAppNameDev)'
                    package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
      
  4. Modificare l'attività per usare la AzureWebApp@1 sottoscrizione.

    1. Selezionare Impostazioni per l'attività.

      Screenshot dell'opzione delle impostazioni nell'attività editor YAML.

    2. Aggiornare il your-subscription valore per la sottoscrizione di Azure per usare la propria sottoscrizione. Potrebbe essere necessario autorizzare l'accesso come parte di questo processo. Se si verifica un problema durante l'autorizzazione della risorsa all'interno dell'editor YAML, un approccio alternativo consiste nel creare una connessione al servizio.

      Screenshot della voce di menu sottoscrizione di Azure.

    3. Impostare Tipo di app su App Web in Linux.

    4. Selezionare Aggiungi per aggiornare l'attività.

  5. Salvare ed eseguire la pipeline.

Aggiungere la fase di gestione temporanea

Infine, la fase di sviluppo verrà promossa alla fase di gestione temporanea. A differenza dell'ambiente di sviluppo, si vuole avere un maggiore controllo nell'ambiente di gestione temporanea che verrà aggiunta un'approvazione manuale.

Creare un ambiente di gestione temporanea

  1. Selezionare Ambienti in Azure Pipelines.

  2. Selezionare Nuovo ambiente.

  3. Creare un nuovo ambiente con il nome staging e Resource impostato su Nessuno.

  4. Nella pagina ambiente di gestione temporanea selezionare Approvazioni e controlli.

    Screenshot dell'opzione di menu Approvazioni e controlli.

  5. Selezionare Approvazioni.

  6. In Responsabili approvazione selezionare Aggiungi utenti e gruppi e quindi selezionare l'account.

  7. In Istruzioni per i responsabili approvazione scrivere Approva questa modifica quando è pronta per la gestione temporanea.

  8. Seleziona Salva.

Aggiungere una nuova fase alla pipeline

Si aggiungerà una nuova fase alla Staging pipeline che include un'approvazione manuale.

  1. Modificare il file della pipeline e aggiungere la Staging sezione .

    trigger:
    - '*'
    
    variables:
      buildConfiguration: 'Release'
      releaseBranchName: 'release'
    
    stages:
    - stage: 'Build'
      displayName: 'Build the web application'
      jobs: 
      - job: 'Build'
        displayName: 'Build job'
        pool:
          vmImage: 'ubuntu-20.04'
          demands:
          - npm
    
        variables:
          wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot'
          dotnetSdkVersion: '6.x'
    
        steps:
        - task: UseDotNet@2
          displayName: 'Use .NET SDK $(dotnetSdkVersion)'
          inputs:
            version: '$(dotnetSdkVersion)'
    
        - task: Npm@1
          displayName: 'Run npm install'
          inputs:
            verbose: false
    
        - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)'
          displayName: 'Compile Sass assets'
    
        - task: gulp@1
          displayName: 'Run gulp tasks'
    
        - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt'
          displayName: 'Write build info'
          workingDirectory: $(wwwrootDir)
    
        - task: DotNetCoreCLI@2
          displayName: 'Restore project dependencies'
          inputs:
            command: 'restore'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Build the project - $(buildConfiguration)'
          inputs:
            command: 'build'
            arguments: '--no-restore --configuration $(buildConfiguration)'
            projects: '**/*.csproj'
    
        - task: DotNetCoreCLI@2
          displayName: 'Publish the project - $(buildConfiguration)'
          inputs:
            command: 'publish'
            projects: '**/*.csproj'
            publishWebProjects: false
            arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'
            zipAfterPublish: true
    
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: drop
    
    - stage: 'Dev'
      displayName: 'Deploy to the dev environment'
      dependsOn: Build
      condition:  succeeded()
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: dev
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'your-subscription'
                  appType: 'webAppLinux'
                  appName: '$(WebAppNameDev)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
    - stage: 'Staging'
      displayName: 'Deploy to the staging environment'
      dependsOn: Dev
      jobs:
      - deployment: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: staging
        variables:
        - group: 'Release'
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: drop
              - task: AzureWebApp@1
                displayName: 'Azure App Service Deploy: website'
                inputs:
                  azureSubscription: 'your-subscription'
                  appType: 'webAppLinux'
                  appName: '$(WebAppNameDev)'
                  package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/*.zip'
    
  2. Modificare l'attività AzureWebApp@1 nella fase di gestione temporanea per usare la sottoscrizione.

    1. Selezionare Impostazioni per l'attività.

      Screenshot dell'opzione delle impostazioni nell'attività editor YAML.

    2. Aggiornare il your-subscription valore per la sottoscrizione di Azure per usare la propria sottoscrizione. Potrebbe essere necessario autorizzare l'accesso come parte di questo processo.

      Screenshot della voce di menu sottoscrizione di Azure.

    3. Impostare Tipo di app su App Web in Linux.

    4. Selezionare Aggiungi per aggiornare l'attività.

  3. Passare all'esecuzione della pipeline. Osservare la compilazione durante l'esecuzione. Quando raggiunge Staging, la pipeline attende l'approvazione manuale del rilascio. Si riceverà anche un messaggio di posta elettronica che contiene un'approvazione della pipeline in sospeso.

    Screenshot dell'attesa dell'approvazione della pipeline.

  4. Esaminare l'approvazione e consentire l'esecuzione della pipeline.

    Screenshot del controllo di convalida manuale.

Pulire le risorse

Se non si intende continuare a usare questa applicazione, eliminare il gruppo di risorse in portale di Azure e il progetto in Azure DevOps seguendo questa procedura:

Per pulire un gruppo di risorse:

  1. Aprire il portale di Azure e accedere.

  2. Scegliere Cloud Shell dalla barra dei menu. Quando viene richiesto, selezionare l'esperienza Bash.

    Screenshot del portale di Azure che mostra la selezione della voce di menu Cloud Shell.

  3. Eseguire il comando az group delete seguente per eliminare il gruppo di risorse usato, tailspin-space-game-rg.

    az group delete --name tailspin-space-game-rg
    

Per eliminare il progetto Azure DevOps, inclusa la pipeline di compilazione:

  1. Passare al proprio progetto in Azure DevOps.

  2. Selezionare Impostazioni progetto.

  3. In Dettagli progetto selezionare Elimina.