Exercício – implantar um aplicativo Azure Functions no Azure

Concluído

Seu projeto veio com um pipeline que compila 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 Azure Functions.

Nesta parte, você vai:

  • Examinar a fase de Build.
  • Adicionar uma tarefa para implantar seu aplicativo de funções.
  • Adicionar uma tarefa para configurar o Serviço de Aplicativo publicado para usar a função publicada.
  • Salvar o pipeline para disparar um fluxo de trabalho de CI/CD.

Examinar a fase de Build

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

  1. No Azure DevOps, acesse Pipelines.

  2. Selecione o pipeline.

  3. Selecione Editar. Verifique se o branch está definido como principal selecionando-o no menu suspenso. Isso abre 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 realçadas abaixo vão restaurar, criar e publicar automaticamente o novo projeto 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
    

Paulo: Este foi nossa fase de build anterior. Eu não o alterei do projeto original porque as tarefas já foram configuradas para serem executadas em todos os projetos com base no padrão de correspondência de curinga.

Clara: Sim, isso deve funcionar como está. Não acho que precisamos fazer nenhuma alteração aqui. Após a execução dessa tarefa de build, os artefatos do arquivo zip para os projetos Web e de placar de líderes serão publicados para a fase de implantação a ser usado.

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

Paulo: Acho que também podemos reutilizar a tarefa de implantação do Serviço de Aplicativo no estado em que se encontra. Espero que haja algo semelhante que possamos usar para implantar um aplicativo de funções.

Clara: Tenho boas notícias. Depois de uma pequena 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 revisá-lo.

Tarefa do aplicativo de funções do Azure

A tarefa AzureFunctionApp@1 foi projetada para implantar aplicativos de funções. Ela é conceitualmente semelhante à tarefa AzureWebApp@1 e inclui tudo o que é necessário para esse cenário de aplicativo de funções:

  • azureSubscription refere-se ao nome da sua 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 de 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 do Linux.
  • startUpCommand especifica o comando de inicialização a ser executado após a implantação da função, que é necessária para implantações do Linux.

Você pode saber mais sobre a flexibilidade dessa tarefa na documentação da Tarefa do aplicativo de funções do Azure.

Adicione o código realçado abaixo ao final do 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'

Dica

Em um arquivo YAML, o espaço em branco é importante. Verifique se a tarefa que você adicionar aqui usa o mesmo recuo da tarefa anterior.

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

Paulo: Agora, tudo o que precisamos fazer é configurar o aplicativo Web para usar a API de placar de líderes publicada. Normalmente, configuramos variáveis no portal, mas seria melhor se pudéssemos fazer isso aqui. Ela espera um parâmetro AppSettings chamado LeaderboardFunctionUrl.

Clara: Concordo. A adição de uma tarefa para isso em nosso pipeline nos ajudará a evitar descuidos mais adiante se alterarmos qualquer serviço. Podemos colocá-la logo no final.

Adicione o código realçado abaixo ao final do pipeline. Certifique-se de corresponder o recuo da tarefa acima dela. Se você quiser saber mais sobre essa tarefa, examine a documentação da tarefa Configurações do Serviço de Aplicativo 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
        }
      ]

Salvar o pipeline para disparar um build e uma versão

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

  2. No Azure Pipelines, acesse o build. Rastreie o build enquanto ele é executado.

  3. Depois que o build for bem-sucedido, escolha a tarefa de implantação do site e selecione a URL para ver o site implantado.

    A screenshot of Azure Pipelines, showing the location of the web site URL.

  4. Você obterá uma página com o site em execução no Serviço de Aplicativo. Role para baixo para confirmar se o placar de líderes tem dados reais. Isso é alimentado pelo aplicativo de funções.

    A screenshot of the Space Game web site.

    Observação

    Se houver um erro ao carregar o placar de líderes, clique duas vezes nas etapas seguidas neste módulo. Se você vir a mensagem de exceção "Foi realizada uma tentativa de acessar um soquete de uma forma proibida por suas permissões de acesso", verifique se a configuração AppSettings__LeaderboardFunctionUrl do serviço de aplicativo foi definida corretamente.

  5. Você também pode testar o aplicativo de funções diretamente. Basta navegar até a URL usando o formato abaixo. A resposta é JSON, que deve ser renderizada como texto em seu navegador.

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

    tal como

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

    A screenshot of a web browser showing the JSON response from the leaderboard API Azure Functions app.

Paulo: Isso ficou ótimo! Todos devem estar muito impressionados com o potencial que mostramos aqui.