Exercício - Implantar um aplicativo do Azure Functions no Azure

Concluído

Seu projeto veio com um pipeline que cria os projetos na solução e implanta o aplicativo Web no Serviço de Aplicativo do Azure. Agora é hora de estender esse pipeline para também implantar o novo projeto do Azure Functions.

Nesta parte, você:

  • Analise o estágio de compilação .
  • Adicione uma tarefa para implantar seu aplicativo de função.
  • Adicionar uma tarefa: configure o Serviço de Aplicativo publicado para usar a função publicada.
  • Salve o pipeline para acionar um fluxo de trabalho de CI/CD.

Revise o estágio de compilação

Aqui, você analisará o pipeline de CI/CD existente definido em azure-pipelines.yml.

  1. No Azure DevOps, navegue até Pipelines.

  2. Selecione o pipeline.

  3. Selecione Editar. Verifique se a ramificação está definida como principal selecionando-a no menu suspenso. Isso exibe o arquivo azure-pipelines.yml que define o pipeline de CI/CD existente.

    Devido ao uso de curingas para os caminhos do projeto, as tarefas destacadas abaixo restaurarão, compilarão e publicarão automaticamente o novo projeto do Azure Functions.

    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.0.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
    

Andy: Este foi o nosso estágio de construção anterior. Não o alterei do projeto original porque as tarefas já estavam configuradas para serem executadas em todos os projetos com base no padrão de correspondência curinga.

Mara: Sim, isso deve funcionar como está. Eu não acho que precisamos fazer nenhuma mudança aqui. Depois que essa tarefa de compilação for executada, os artefatos de arquivo zip para os projetos da Web e da tabela de classificação serão publicados para o estágio Implantar a ser usado.

Adicionar uma tarefa para implantar a Função do Azure

Andy: Acho que também podemos reutilizar a tarefa de implantação do Serviço de Aplicativo como está. Espero que haja algo semelhante que possamos usar para implantar um aplicativo de função.

Mara: Tenho boas notícias. Depois de um pouco de pesquisa, parece que há uma tarefa conceitualmente semelhante à tarefa de implantação do Serviço de Aplicativo, mas para implantações do Azure Functions. Vamos revê-lo agora.

Tarefa do Aplicativo Azure Function

A AzureFunctionApp@1 tarefa foi projetada para implantar aplicativos funcionais. É conceitualmente semelhante à tarefa e inclui tudo o AzureWebApp@1 que é necessário para este cenário de aplicativo de função:

  • azureSubscription refere-se ao nome da variável de pipeline de conexão de serviço do Azure.
  • appType indica se o aplicativo está sendo implantado para Linux (functionAppLinux) ou Windows (functionApp).
  • appName especifica o nome da instância do aplicativo Azure Functions em sua conta do Azure.
  • package Especifica o caminho para o pacote a ser implantado.
  • runtimeStack indica em qual imagem a função deve ser executada, o que é necessário para implantações Linux.
  • startUpCommand especifica o comando de inicialização a ser executado após a implantação da função, que é necessário para implantações do Linux.

Você pode saber mais sobre a flexibilidade dessa tarefa na documentação da tarefa Aplicativo de Função do Azure.

Adicione o seguinte código realçado ao final do seu pipeline.

- stage: 'Deploy'
  displayName: 'Deploy the web application'
  dependsOn: Build
  jobs:
  - deployment: Deploy
    pool:
      vmImage: 'ubuntu-20.04'
    environment: spike
    variables:
    - group: Release
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: drop
          - task: AzureWebApp@1
            displayName: 'Azure App Service Deploy: website'
            inputs:
              azureSubscription: 'Resource Manager - Tailspin - Space Game'
              appName: '$(WebAppName)'
              appType: webAppLinux
              package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/Tailspin.SpaceGame.Web.zip'

          - task: AzureFunctionApp@1
            displayName: 'Azure Function Deploy: leaderboard'
            inputs:
              azureSubscription: 'Resource Manager - Tailspin - Space Game'
              appType: functionAppLinux
              appName: '$(LeaderboardAppName)'
              package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/Tailspin.SpaceGame.LeaderboardFunction.zip'
              runtimeStack: DOCKER|microsoft/azure-functions-dotnet:4
              startUpCommand: 'func azure functionapp publish $(functionAppName) --no-bundler'

Gorjeta

Em um arquivo YAML, o espaço em branco é importante. Certifique-se de que a tarefa adicionada aqui usa o mesmo recuo que a tarefa anterior.

Adicionar uma tarefa para atualizar as configurações do aplicativo do Serviço de Aplicativo

Andy: Agora tudo o que precisamos fazer é configurar o aplicativo Web para usar a API de tabela de classificação publicada. Normalmente configuramos variáveis no portal, mas seria melhor se pudéssemos fazê-lo aqui. Ele espera um parâmetro AppSettings chamado LeaderboardFunctionUrl.

Mara: Concordo. Adicionar uma tarefa para isso ao nosso pipeline nos ajudará a evitar descuidos acidentais no futuro, se mudarmos qualquer um dos serviços. Podemos corrigi-lo no final.

Adicione o seguinte código realçado ao final do seu pipeline. Certifique-se de corresponder ao recuo da tarefa acima dela. Se quiser saber mais sobre esta tarefa, pode rever os documentos para a tarefa Definições do Serviço de Aplicações do Azure.

- task: AzureFunctionApp@1
  displayName: 'Azure Function Deploy: leaderboard'
  inputs:
    azureSubscription: 'Resource Manager - Tailspin - Space Game'
    appType: functionAppLinux
    appName: '$(LeaderboardAppName)'
    package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/Tailspin.SpaceGame.LeaderboardFunction.zip'
    runtimeStack: DOCKER|microsoft/azure-functions-dotnet:4
    startUpCommand: 'func azure functionapp publish $(functionAppName) --no-bundler'

- task: AzureAppServiceSettings@1
  displayName: 'Update web app settings'
  inputs:
    azureSubscription: 'Resource Manager - Tailspin - Space Game'
    appName: $(WebAppName)
    resourceGroupName: $(ResourceGroupName)
    appSettings: |
      [
        {
          "name": "AppSettings__LeaderboardFunctionUrl",
          "value": "http://$(LeaderboardAppName).azurewebsites.net/api/LeaderboardFunction",
          "slotSetting": false
        }
      ]

Salve o pipeline para acionar uma compilação e liberação

  1. Selecione Salvar no canto superior direito da página. Confirme a opção Salvar para acionar uma execução.

  2. No Azure Pipelines, vá para a compilação. Rastreie a compilação enquanto ela é executada.

  3. Depois que a compilação for bem-sucedida, selecione a tarefa de implantação do site e selecione a URL para exibir o site implantado.

    Uma captura de tela do Azure Pipelines, mostrando o local da URL do site.

  4. Você receberá uma página com o site em execução no Serviço de Aplicativo. Role para baixo para confirmar se a tabela de classificação tem dados reais. Isso é alimentado pelo aplicativo de função.

    Uma captura de tela do site Space Game.

    Nota

    Se houver um erro ao carregar a tabela de classificação, verifique novamente as etapas seguidas neste módulo. Se vir a mensagem de exceção "Foi feita uma tentativa de aceder a uma tomada de uma forma proibida pelas respetivas permissões de acesso", certifique-se de que a definição de AppSettings__LeaderboardFunctionUrl do serviço da aplicação está a ser definida corretamente.

  5. Você também pode testar o aplicativo de função diretamente. Basta navegar até ao seu URL utilizando o seguinte formato. A resposta é JSON, que deve apenas renderizar como texto em seu navegador.

    http://<leaderboard function name>.azurewebsites.net/api/LeaderboardFunction?pageSize=10
    

    tais como:

    http://tailspin-space-game-leaderboard-4692.azurewebsites.net/api/LeaderboardFunction?pageSize=10
    

Andy: Isso ficou ótimo! Todos devem ficar bastante impressionados com o potencial que mostramos aqui.