Usar o Azure Pipelines para criar e implantar um aplicativo Web Python no Serviço de Aplicativo do Azure

Azure DevOps Services

Use o Azure Pipelines para criar e implantar com CI/CD (integração contínua e entrega contínua) um aplicativo Web Python no Serviço de Aplicativo do Azure no Linux. Seu pipeline cria e implanta automaticamente seu aplicativo Web Python no Serviço de Aplicativo sempre que houver uma confirmação no repositório.

Neste artigo, você aprenderá como:

  • Criar um aplicativo Web no Serviço de Aplicativo do Azure.
  • Crie um projeto no Azure DevOps.
  • Conecte seu projeto do DevOps ao Azure.
  • Crie um pipeline específico do Python.
  • Execute o pipeline para criar e implantar seu aplicativo Web no Serviço de Aplicativo.

Pré-requisitos

Criar um repositório para o código do aplicativo

Bifurque o repositório de amostra em https://github.com/Microsoft/python-sample-vscode-flask-tutorial para sua conta do GitHub.

No host local, clone seu repositório do GitHub. Use o comando a seguir, substituindo <repository-url> pela URL do repositório bifurcado.

git clone <repository-url>

Testar o aplicativo no local

Compile e execute o aplicativo no local para verificar se ele funciona.

  1. Altere para a pasta do repositório clonado.

    cd python-sample-vscode-flask-tutorial
    
  2. Compilar e executar o aplicativo

    python -m venv .env
    source .env/bin/activate
    pip install --upgrade pip
    pip install -r ./requirements.txt
    export set FLASK_APP=hello_app.webapp
    python3 -m flask run
    
  3. Para exibir o aplicativo, abra uma janela do navegador e acesse http://localhost:5000. Verifique se você vê o título Visual Studio Flask Tutorial.

  4. Quando terminar, feche a janela do navegador e interrompa o servidor Flask com Ctrl+C.

Abrir um Cloud Shell

  1. Entre no portal do Azure emhttps://portal.azure.com.

  2. Abra a CLI do Azure selecionando o botão Cloud Shell na barra de ferramentas do portal.

    Captura de tela do botão Azure Cloud Shell na barra de ferramentas do portal do Azure.

  3. O Cloud Shell será exibido na parte inferior do navegador. Selecione Bash no menu suspenso.

    Captura de tela do Azure Cloud Shell.

  4. Para obter mais espaço para trabalhar, selecione o botão Maximizar.

Criar um aplicativo Web do Serviço de Aplicativo do Azure

Crie seu aplicativo Web do Serviço de Aplicativo do Azure a partir do Cloud Shell no portal do Azure.

Dica

Para colar no Cloud Shell, use Ctrl+Shift+V ou clique com o botão direito do mouse e selecione Colar no menu de contexto.

  1. Clone seu repositório com o comando a seguir, substituindo <repository-url> pela URL do repositório bifurcado.

    git clone <repository-url>
    
  2. Altere o diretório para a pasta do repositório clonado para que o comando az webapp up reconheça o aplicativo como um aplicativo Python.

    cd python-sample-vscode-flask-tutorial
    
  3. Use o comando az webapp up para provisionar o Serviço de Aplicativo e fazer a primeira implantação do seu aplicativo. Substitua <your-web-app-name> por um nome que seja exclusivo em todo o Azure. Normalmente, você usa o nome de uma pessoa ou razão social junto com um identificador de aplicativo, como <your-name>-flaskpipelines. A URL do aplicativo se torna <your-appservice.azurewebsites.net>.

    az webapp up --name <your-web-app-name>
    

    A saída JSON do comando az webapp up mostra:

    {
      "URL": <your-web-app-url>,
      "appserviceplan": <your-app-service-plan-name>,
      "location": <your-azure-location>,
      "name": <your-web-app-name>,
      "os": "Linux",
      "resourcegroup": <your-resource-group>,
      "runtime_version": "python|3.11",
      "runtime_version_detected": "-",
      "sku": <sku>,
      "src_path": <repository-source-path>
    }
    

    Observe os valores URL e runtime_version. Use runtime_version no arquivo YAML do pipeline. URL é a URL do aplicativo Web. Você pode usá-la para verificar se o aplicativo está em execução.

    Observação

    O comando az webapp up realiza as seguintes ações:

    • Criar um grupo de recursos padrão.

    • Criar um plano do Serviço de Aplicativo padrão.

    • Criar um aplicativo com o nome especificado.

    • Implantar o zip de todos os arquivos do diretório de trabalho atual, com a automação de build habilitada.

    • Armazene em cache os parâmetros localmente no arquivo .azure/config para que você não precise especificá-los novamente na implantação posterior com az webapp up ou outros comandos az webapp da pasta do projeto. Os valores armazenados em cache são usados automaticamente por padrão.

    Você pode substituir a ação padrão por seus próprios valores usando os parâmetros de comando. Para obter mais informações, confira az webapp up.

  4. O aplicativo python-sample-vscode-flask-tutorial tem um arquivo startup.txt que contém o comando de inicialização específico para o aplicativo Web. Defina a propriedade de configuração do aplicativo Web startup-file como startup.txt.

    1. Na saída do comando az webapp up, copie o valor resourcegroup.

    2. Insira o comando a seguir usando o grupo de recursos e o nome do aplicativo.

    az webapp config set --resource-group <your-resource-group> --name <your-web-app-name> --startup-file startup.txt
    

    Quando o comando for concluído, ele mostrará a saída JSON que contém todas as definições de configuração para seu aplicativo Web.

  5. Para ver o aplicativo em execução, abra um navegador e vá para URL mostrado na saída do comando az webapp up. Se for exibida uma página genérica, aguarde alguns segundos para que o Serviço de Aplicativo seja iniciado e atualize a página. Verifique se você vê o título Visual Studio Flask Tutorial.

Criar um projeto do Azure DevOps

Crie um novo projeto do Azure DevOps.

  1. Em um navegador, acesse dev.azure.com e entre.
  2. Selecione sua organização.
  3. Crie um novo projeto selecionando Novo projeto ou Criar projeto se estiver criando o primeiro projeto na organização.
  4. Insira um Nome de projeto.
  5. Selecione a Visibilidade do seu projeto.
  6. Selecione Criar.
  1. Em um navegador, acesse Azure DevOps Server.
  2. Selecione sua coleção.
  3. Crie um novo projeto selecionando Novo projeto ou Criar projeto se estiver criando o primeiro projeto da coleção.
  4. Insira um Nome de projeto.
  5. Selecione a Visibilidade do seu projeto.
  6. Selecione Criar.

Criar uma entidade de serviço

Uma entidade de serviço é uma identidade criada para uso com aplicativos, serviços hospedados e ferramentas automatizadas a fim de acessar recursos do Azure. Esse acesso é restrito para funções atribuídas à entidade de serviço, oferecendo a você o controle sobre quais recursos poderão ser acessados e em qual nível.

Para criar uma entidade de serviço, vá para o Cloud Shell (bash) e execute o comando a seguir. Substitua <service-principal-name> por um nome para sua entidade de serviço, <your-subscription-id> pela sua ID de assinatura e <your-resource-group> pelo grupo de recursos para o aplicativo Web.

az ad sp create-for-rbac --display-name <service-principal-name> --role contributor --scopes /subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>

O comando retorna um objeto JSON semelhantes ao seguinte exemplo:

{
  "clientId": "<client GUID>",
  "clientSecret": "<string-value>",
  "subscriptionId": "<subscription GUID>",
  "tenantId": "<tenant GUID>",
  ...
}

Anote os valores clientId, clientSecret, subscriptionId e tenantId. Você precisa deles para criar uma conexão de serviço na próxima seção.

Criar uma conexão de serviço

Uma conexão de serviço permite que você crie uma conexão para fornecer acesso autenticado do Azure Pipelines a serviços externos e remotos. Para implantar em seu aplicativo Web do Serviço de Aplicativo do Azure, crie uma conexão de serviço com o grupo de recursos que contém o aplicativo Web.

  1. Na página do projeto, selecione Configurações do projeto.

    Captura de tela do botão de configurações do projeto no painel do projeto.

  2. Selecione Conexões de serviço na seção Pipelines do menu.

  3. Selecione Criar conexão de serviço.

  4. Selecione Azure Resource Manager e selecione Avançar.

    Captura de tela da seleção de conexão de serviço do Azure Resource Manager.

  5. Selecione seu método de autenticação e selecione Avançar.

  6. Na caixa de diálogo Nova conexão de serviço do Azure, insira as informações específicas do método de autenticação selecionado. Para obter mais informações sobre métodos de autenticação, consulte Conectar-se ao Azure usando uma conexão de serviço do Azure Resource Manager.

    Por exemplo, se você estiver usando um método de autenticação Federação de identidade de carga de trabalho (automático) ou Entidade de serviço (automático) insira as informações necessárias.

    Captura de tela da caixa de diálogo Nova conexão de serviço.

    Campo Descrição
    Scope level Selecione a Assinatura.
    Assinatura Seu nome da assinatura do Azure.
    Grupo de recursos O nome do grupo de recursos que contém o seu aplicativo Web.
    Service connection name Um nome descritivo para a conexão.
    Conceder permissões de acesso a todos os pipelines Selecione essa opção para conceder acesso a todos os pipelines.
  7. Selecione Salvar.

A nova conexão aparece na lista Conexões de serviço e está pronta para uso no seu pipeline do Azure.

  1. Na página do projeto, selecione Configurações do projeto.

    Captura de tela do botão de configurações do projeto no painel do projeto.

  2. Selecione Conexões de serviço na seção Pipelines do menu.

  3. Selecione Criar conexão de serviço.

  4. Selecione Azure Resource Manager e selecione Avançar.

    Captura de tela da seleção de conexão de serviço do Azure Resource Manager.

  5. Em Nova conexão de serviço do Azure, selecione Entidade de serviço (manual) e selecione Avançar

  6. Na próxima caixa de diálogo, preencha as informações necessárias.

    Captura de tela da caixa de diálogo Nova conexão de serviço.

    Campo Descrição
    Ambiente Selecione Azure Cloud.
    Scope level Selecione a Assinatura.
    ID da assinatura A ID de sua assinatura.
    Nome da assinatura Seu nome da assinatura do Azure.
    Service Principal (ID da Entidade de Serviço) O valor appId do objeto JSON retornado pelo comando az ad sp create-for-rbac.
    Chave da Entidade de Serviço O valor password do objeto JSON retornado pelo comando az ad sp create-for-rbac.
    ID do locatário O valor tenant do objeto JSON retornado pelo comando az ad sp create-for-rbac.
  7. Selecione Verificar para verificar a conexão.

  8. Insira o nome de uma conexão de serviço.

  9. Verifique se a opção Conceder permissões de acesso a todos os pipelines está selecionada.

  10. Selecione Verificar e salvar.

A nova conexão será exibida na lista Conexões de serviço e estará pronta para o Azure Pipelines usar no projeto.

Configurar um agente auto-hospedado

Se estiver usando seu próprio agente auto-hospedado, você precisará configurar o agente para executar o Python. O download de versões do Python não é suportado em agentes auto-hospedados. Você deve pré-instalar a versão do Python. Use o instalador completo para obter uma versão compatível com pip do Python.

Para evitar problemas de incompatibilidade, você deve corresponder a versão do Python com a versão de runtime em seu aplicativo Web dos Serviços de Aplicativo do Azure. A versão de runtime é mostrada na saída JSON do comando az webapp up.

A versão desejada do Python precisa ser adicionada ao cache de ferramentas no agente auto-hospedado para que a tarefa possa usá-la. Normalmente, o cache da ferramenta está localizado no diretório _work/_tool do agente. Como alternativa, o caminho pode ser substituído pela variável de ambiente AGENT_TOOLSDIRECTORY. No diretório de ferramentas, crie a seguinte estrutura de diretórios com base na sua versão do Python:

$AGENT_TOOLSDIRECTORY/
    Python/
        {version number}/
            {platform}/
                {tool files}
            {platform}.complete

O número de versão deve seguir o formato 1.2.3. A plataforma deve ser x86 ou x64. Os arquivos de ferramenta devem ser os arquivos de versão Python descompactados. {platform}.complete deve ser um arquivo de 0 byte que se parece com x86.complete ou com x64.complete, significando apenas que a ferramenta está instalada corretamente no cache.

Por exemplo, se você estiver usando o Python 3.11 em um computador Windows de 64 bits, a estrutura de diretórios terá a seguinte aparência:

$AGENT_TOOLSDIRECTORY/
    Python/
        3.11.4/
            x64/
                {python files}
            x64.complete

Se já tiver a versão do Python que deseja usar no computador que hospeda seu agente, você poderá copiar os arquivos para o cache da ferramenta. Se não tiver a versão do Python, você poderá baixá-la no site do Python.

Criar um pipeline

Crie um pipeline para compilar e implantar seu aplicativo Web Python no Serviço de Aplicativo do Azure. Para entender os conceitos de pipeline, assista:

  1. No menu de navegação esquerdo, selecione Pipelines.

    Captura de tela da seleção de pipelines no painel do projeto.

  2. Selecione Criar pipeline.

    Captura de tela do novo botão de pipeline na lista de pipelines.

  3. Na caixa de diálogo Onde está o código?, selecione GitHub. Talvez você receba uma solicitação para entrar no GitHub.

    Captura de tela da seleção do GitHub como o local do seu código.

  4. Na tela Selecionar um repositório, selecione o repositório de amostra bifurcado.

    Captura de tela da seleção do repositório.

  5. Pode ser solicitado que você insira sua senha do GitHub novamente como uma confirmação.

  6. Se a extensão do Azure Pipelines não estiver instalada no GitHub, este solicitará que você instale a extensão do Azure Pipelines.

    instale a extensão do Azure Pipelines no GitHub.

    Nessa página, role para baixo até a seção Acesso ao repositório, escolha se deseja instalar a extensão em todos os repositórios ou apenas nos selecionados e selecione Aprovar e instalar.

    Captura de tela da extensão Aprovar e Instalar o Azure Pipelines no GitHub.

  7. Na caixa de diálogo Configurar seu pipeline, selecione Aplicativo Web Python para Linux no Azure.

  8. Escolha sua assinatura do Azure e selecione Continuar.

  9. Se você estiver usando seu nome de usuário e senha para autenticar, um navegador será aberto para você entrar na sua conta da Microsoft.

  10. Escolha o nome do aplicativo Web na lista suspensa e selecione Validar e configurar.

O Azure Pipelines cria um arquivo azure-pipelines.yml e o exibe no editor de pipelines YAML. O arquivo de pipeline define seu pipeline de CI/CD como uma série de fases, Trabalhos e etapas, e cada etapa contém os detalhes de diferentes tarefas e scripts. Dê uma olhada no pipeline para compreender o que ele faz. Verifique se todas as entradas padrão são apropriadas para seu código.

  1. No menu de navegação, selecione Pipelines.

    Captura de tela da seleção de pipelines no painel do projeto.

  2. Selecione Criar pipeline.

    Captura de tela do botão Novo pipeline.

  3. Na caixa de diálogo Onde está o código?, selecione GitHub Enterprise Server. Talvez você receba uma solicitação para entrar no GitHub.

    Captura de tela da seleção do GitHub como o local do seu código.

  4. Na guia Selecionar um repositório, selecione o repositório de amostra bifurcado.

    Captura de tela da seleção do repositório.

  5. Pode ser solicitado que você insira sua senha do GitHub novamente como uma confirmação.

  6. Se a extensão do Azure Pipelines não estiver instalada no GitHub, este solicitará que você instale a extensão do Azure Pipelines.

    Captura de tela da extensão do Azure Pipelines no GitHub.

    Nessa página, role para baixo até a seção Acesso ao repositório, escolha se deseja instalar a extensão em todos os repositórios ou apenas nos selecionados e selecione Aprovar e instalar.

    Captura de tela da extensão Aprovar e Instalar o Azure Pipelines no GitHub.

  7. Na caixa de diálogo Configurar seu pipeline, selecione Pipeline inicial.

  8. Substitua o conteúdo do arquivo azure-pipelines.yml pelo código a seguir.

    trigger:
    - main
    
    variables:
      # Azure Resource Manager connection created during pipeline creation
      azureServiceConnectionId: '<your-service-connection-name>'
    
      # Web app name
      webAppName: '<your-web-app-name>'
    
      # Environment name
      environmentName: '<your-web-app-name>'
    
      # Project root folder. 
      projectRoot: $(System.DefaultWorkingDirectory)
    
      # Python version: 
      pythonVersion: '<your-python-version>'
    
    stages:
    - stage: Build
      displayName: Build stage
      jobs:
      - job: BuildJob
        pool:
          name: '<your-pool-name>'
          demands: python
        steps:
        - task: UsePythonVersion@0
          inputs:
            versionSpec: '$(pythonVersion)'
          displayName: 'Use Python $(pythonVersion)'
    
        - script: |
            python -m venv antenv
            source antenv/bin/activate
            python -m pip install --upgrade pip
            pip install setup
            pip install -r requirements.txt
          workingDirectory: $(projectRoot)
          displayName: "Install requirements"
    
        - task: ArchiveFiles@2
          displayName: 'Archive files'
          inputs:
            rootFolderOrFile: '$(projectRoot)'
            includeRootFolder: false
            archiveType: zip
            archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
            replaceExistingArchive: true
    
        - task: PublishBuildArtifacts@1
          inputs:
            PathtoPublish: '$(Build.ArtifactStagingDirectory)'
            ArtifactName: 'drop'
            publishLocation: 'Container'
    
    - stage: Deploy
      displayName: 'Deploy Web App'
      dependsOn: Build
      condition: succeeded()
      jobs:
      - deployment: DeploymentJob
        pool:
          name: '<your-pool-name'
        environment: $(environmentName)
        strategy:
          runOnce:
            deploy:
              steps:
    
              - task: UsePythonVersion@0
                inputs:
                  versionSpec: '$(pythonVersion)'
                displayName: 'Use Python version'
    
              - task: AzureWebApp@1
                displayName: 'Deploy Azure Web App : <your-web-app-name>'
                inputs:
                  azureSubscription: $(azureServiceConnectionId)
                  appName: $(webAppName)
                  package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
                  startUpCommand: 'startup.txt'
    
    
  9. Substitua os espaços reservados a seguir pelos seus próprios valores:

    Espaço reservado Descrição
    <your-service-connection-name> O nome da conexão de serviço que você criou.
    <your-web-app-name> O nome do seu aplicativo Web do Serviço de Aplicativo do Azure.
    <your-pool-name> O nome do pool de agentes que você deseja usar.
    <your-python-version> A versão do Python em execução no seu agente. É uma boa ideia combinar essa versão com a versão do Python em execução no seu aplicativo Web. A versão de aplicativo Web é mostrada na saída JSON do comando az webapp up.

Arquivo de pipeline YAML

A explicação a seguir descreve o arquivo de pipeline YAML. Para saber mais sobre o esquema de arquivo YAML de pipeline, consulte Referência de esquema YAML.

O arquivo YAML de pipeline de exemplo completo é mostrado abaixo:

trigger:
- main

variables:
  # Azure Resource Manager connection created during pipeline creation
  azureServiceConnectionId: '<GUID>'

  # Web app name
  webAppName: '<your-webapp-name>'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

  # Environment name
  environmentName: '<your-webapp-name>'

  # Project root folder. Point to the folder containing manage.py file.
  projectRoot: $(System.DefaultWorkingDirectory)

  pythonVersion: '3.11'

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: BuildJob
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: UsePythonVersion@0
      inputs:
        versionSpec: '$(pythonVersion)'
      displayName: 'Use Python $(pythonVersion)'

    - script: |
        python -m venv antenv
        source antenv/bin/activate
        python -m pip install --upgrade pip
        pip install setup
        pip install -r requirements.txt
      workingDirectory: $(projectRoot)
      displayName: "Install requirements"

    - task: ArchiveFiles@2
      displayName: 'Archive files'
      inputs:
        rootFolderOrFile: '$(projectRoot)'
        includeRootFolder: false
        archiveType: zip
        archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
        replaceExistingArchive: true

    - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
      displayName: 'Upload package'
      artifact: drop

- stage: Deploy
  displayName: 'Deploy Web App'
  dependsOn: Build
  condition: succeeded()
  jobs:
  - deployment: DeploymentJob
    pool:
      vmImage: $(vmImageName)
    environment: $(environmentName)
    strategy:
      runOnce:
        deploy:
          steps:

          - task: UsePythonVersion@0
            inputs:
              versionSpec: '$(pythonVersion)'
            displayName: 'Use Python version'

          - task: AzureWebApp@1
            displayName: 'Deploy Azure Web App : $(webAppName)'
            inputs:
              azureSubscription: $(azureServiceConnectionId)
              appName: $(webAppName)
              package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip

Variáveis

A seção variables contém as seguintes variáveis:

variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<GUID>'

# Web app name
webAppName: '<your-webapp-name>'

# Agent VM image name
vmImageName: 'ubuntu-latest'

# Environment name
environmentName: '<your-webapp-name>'

# Project root folder.
projectRoot: $(System.DefaultWorkingDirectory)

# Python version: 3.11. Change this to match the Python runtime version running on your web app.
pythonVersion: '3.11'

Variável Descrição
azureServiceConnectionId A ID ou o nome da conexão de serviço do Azure Resource Manager.
webAppName O nome do aplicativo Web do Serviço de Aplicativo do Azure.
vmImageName O nome do sistema operacional a ser usado para o agente de compilação.
environmentName O nome do ambiente usado no estágio de implantação. O ambiente é criado automaticamente quando o trabalho de estágio é executado.
projectRoot A pasta raiz que contém o código do aplicativo.
pythonVersion A versão do Python a ser usada nos agentes de compilação e implantação.

A seção variables contém as seguintes variáveis:

variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<your-service-connection-name>'

# Web app name
webAppName: '<your-webapp-name>'

# Environment name
environmentName: '<your-webapp-name>'

# Project root folder. 
projectRoot: $(System.DefaultWorkingDirectory)

# Python version: 3.11. Change this to the version that is running on your agent and web app.
pythonVersion: '3.11'
Variável Descrição
azureServiceConnectionId O nome da conexão de serviço do Azure Resource Manager.
webAppName O nome do aplicativo Web.
environmentName O nome do ambiente usado no estágio de implantação.
projectRoot A pasta que contém o código do aplicativo. O valor é uma variável de sistema automática.
pythonVersion A versão do Python a ser usada nos agentes de compilação e implantação.

Fase de build

O estágio de compilação contém um único trabalho que é executado no sistema operacional definido na variável vmImageName.

  - job: BuildJob
    pool:
      vmImage: $(vmImageName)

O estágio de compilação contém um único trabalho que é executado em um agente no pool identificado pelo parâmetro de nome. Você pode especificar os recursos do agente com a palavra-chave demands. Por exemplo, demands: python especifica que o agente deve ter o Python instalado. Para especificar um agente auto-hospedado pelo nome, você pode usar a palavra-chave demands: Agent.Name -equals <agent-name>.

  - job: BuildJob
    pool:
      name: <your-pool-name>
      demands: python

O trabalho contém várias etapas:

  1. A tarefa UsePythonVersion seleciona a versão do Python a ser usada. A versão é definida na variável pythonVersion.

       - task: UsePythonVersion@0
          inputs:
            versionSpec: '$(pythonVersion)'
            displayName: 'Use Python $(pythonVersion)'
    
  2. Esta etapa usa um script para criar um ambiente virtual do Python e instalar as dependências do aplicativo contidas no requirements.txt parâmetro O workingDirectory parâmetro especifica o local do código do aplicativo.

      - script: |
           python -m venv antenv
           source antenv/bin/activate
           python -m pip install --upgrade pip
           pip install setup
           pip install  -r ./requirements.txt
         workingDirectory: $(projectRoot)
         displayName: "Install requirements"
    
  3. A tarefa ArchiveFiles cria o arquivo .zip que contém o aplicativo Web. O arquivo .zip é carregado no pipeline como o artefato chamado drop. O arquivo .zip é usado no estágio de implantação para implantar o aplicativo no aplicativo Web.

       - task: ArchiveFiles@2
         displayName: 'Archive files'
         inputs:
           rootFolderOrFile: '$(projectRoot)'
           includeRootFolder: false
           archiveType: zip
           archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
           replaceExistingArchive: true
    
       - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
         displayName: 'Upload package'
         artifact: drop
    
    Parâmetro Descrição
    rootFolderOrFile O local do código do aplicativo.
    includeRootFolder Indica se a pasta raiz deve ser incluída no arquivo .zip. Defina esse parâmetro para false, caso contrário, o conteúdo do arquivo .zip será colocado em uma pasta chamada s e o contêiner do Serviço de Aplicativo no Linux não conseguirá localizar o código do aplicativo.
    archiveType O tipo de arquivo a ser criado. Defina como zip.
    archiveFile O local do arquivo .zip a ser criado.
    replaceExistingArchive Indica se um arquivo existente deve ser substituído se o arquivo já existir. Defina como true.
    upload O local do arquivo .zip a ser carregado.
    artifact O nome do artefato de compilação a ser criado.

Etapa de implantação

O estágio de implantação será executado se o estágio de compilação for concluído com êxito. As palavras-chave a seguir definem esse comportamento:

  dependsOn: Build
  condition: succeeded()

O estágio de implantação contém um único trabalho de implantação configurado com as seguintes palavras-chave:

  - deployment: DeploymentJob
    pool:
      vmImage: $(vmImageName)
    environment: $(environmentName)
Palavra-chave Descrição
deployment Indica que o trabalho é um trabalho de implantação direcionado a um ambiente.
pool Especifica o pool de agentes de implantação. O pool de agentes padrão se o nome não for especificado. A palavra-chave vmImage identifica o sistema operacional para a imagem da máquina virtual do agente
environment Especifica o ambiente no qual implantar. O ambiente é criado automaticamente em seu projeto quando o trabalho é executado.
  - deployment: DeploymentJob
    pool:
      name: <your-pool-name>
    environment: $(environmentName)
Palavra-chave Descrição
deployment Indica que o trabalho é um trabalho de implantação direcionado a um ambiente.
pool Especifica o pool de agentes a ser usado para implantação. Esse pool deve conter um agente com a capacidade de executar a versão python especificada no pipeline.
environment Especifica o ambiente no qual implantar. O ambiente é criado automaticamente em seu projeto quando o trabalho é executado.

A palavra-chave strategy é usada para definir a estratégia de implantação. A palavra-chave runOnce especifica que o trabalho de implantação é executado uma vez. A palavra-chave deploy especifica as etapas a serem executadas no trabalho de implantação.

  strategy:
    runOnce:
      deploy:
        steps:

As steps no pipeline são:

  1. Usar a tarefa UsePythonVersion para especificar a versão do Python a ser usada no agente. A versão é definida na variável pythonVersion.

     - task: UsePythonVersion@0
       inputs:
         versionSpec: '$(pythonVersion)'
       displayName: 'Use Python version'
    
  2. Implantar o aplicativo Web usando AzureWebApp@1. Essa tarefa implanta o artefato de pipeline drop em seu aplicativo Web.

    - task: AzureWebApp@1
       displayName: 'Deploy Azure Web App : <your-web-app-name>'
       inputs:
          azureSubscription: $(azureServiceConnectionId)
          appName: $(webAppName)
          package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
    
    Parâmetro Descrição
    azureSubscription A ID ou nome a ser usado pela conexão de serviço do Azure Resource Manager.
    appName O nome do aplicativo Web.
    package O local do arquivo .zip a ser implantado.

    Além disso, como o repositório python-vscode-flask-tutorial contém o mesmo comando de inicialização em um arquivo chamado startup.txt, você pode especificar esse arquivo adicionando o parâmetro: startUpCommand: 'startup.txt'.

As steps no pipeline são:

  1. Usar a tarefa UsePythonVersion para especificar a versão do Python a ser usada no agente. A versão é definida na variável pythonVersion.

     - task: UsePythonVersion@0
       inputs:
         versionSpec: '$(pythonVersion)'
       displayName: 'Use Python version'
    
  2. Implantar o aplicativo Web usando AzureWebApp@1. Essa tarefa implanta o artefato de pipeline drop em seu aplicativo Web.

    - task: AzureWebApp@1
       displayName: 'Deploy Azure Web App : <your-web-app-name>'
       inputs:
          azureSubscription: $(azureServiceConnectionId)
          appName: $(webAppName)
          package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
    
    Parâmetro Descrição
    azureSubscription A ID ou nome a ser usado pela conexão de serviço do Azure Resource Manager.
    appName O nome do aplicativo Web.
    package O local do arquivo .zip a ser implantado.

    Além disso, como o repositório python-vscode-flask-tutorial contém o mesmo comando de inicialização em um arquivo chamado startup.txt, você pode especificar esse arquivo adicionando o parâmetro: startUpCommand: 'startup.txt'.

      - task: AzureWebApp@1
         displayName: 'Deploy Azure Web App : $(webAppName)'
         inputs:
           azureSubscription: $(azureServiceConnectionId)
           appName: $(webAppName)
           package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
           startUpCommand: 'startup.txt'
    
    Parâmetro Descrição
    azureSubscription A ID ou nome a ser usado pela conexão de serviço do Azure Resource Manager.
    appName O nome do aplicativo Web.
    package O local do arquivo .zip a ser implantado.
    startUpCommand O comando a ser executado após a implantação do aplicativo. O aplicativo de exemplo usa startup.txt.

Executar o pipeline

Agora você está pronto para experimentar!

  1. No editor, selecione Salvar e executar.

  2. Na caixa de diálogo Salvar e executar, adicione uma mensagem de confirmação e selecione Salvar e executar.

    Você pode observar o pipeline enquanto ele é executado selecionando as Estágios ou Trabalhos no resumo de execução do pipeline.

    Captura de tela da seção de estágios do resumo de execução do pipeline.

    Marcas de seleção verdes aparecem ao lado de cada estágio e trabalho à medida que ele é concluído com êxito. Se ocorrerem erros, eles serão exibidos no resumo ou nas etapas do trabalho.

    Captura de tela das etapas do estágio do pipeline.

    Você pode retornar rapidamente ao editor YAML selecionando os pontos verticais no canto superior direito da página Resumo e selecionando Editar pipeline:

    Captura de tela do comentário de edição do pipeline em um relatório de compilação.

  3. No trabalho de implantação, selecione a tarefa Implantar Aplicativo Web do Azure para exibir sua saída. Para visitar o site implantado, mantenha pressionada a tecla Ctrl e selecione a URL depois de App Service Application URL.

    Se você estiver usando o aplicativo de exemplo, o aplicativo deverá aparecer da seguinte maneira:

    Captura de tela do modo de exibição do aplicativo de exemplo em execução no Serviço de Aplicativo.

Importante

Se o aplicativo falhar devido a uma dependência ausente, o arquivorequirements.txt não foi processado durante a implantação. Esse comportamento ocorrerá se você tiver criado o aplicativo Web diretamente no portal, em vez de usar o comando az webapp up, conforme mostrado neste artigo.

O comando az webapp up define especificamente a ação de build SCM_DO_BUILD_DURING_DEPLOYMENT como true. Se você provisionou o serviço de aplicativo por meio do portal, essa ação não será definida automaticamente.

As etapas a seguir definem a ação:

  1. Abra o portal do Azure, selecione o Serviço de Aplicativo e, em seguida, Configuração.
  2. Na guia Configurações do Aplicativo, selecione Nova Configuração do Aplicativo.
  3. No pop-up exibido, defina Nome como SCM_DO_BUILD_DURING_DEPLOYMENT, defina Valor como true e selecione OK.
  4. Selecione Salvar na parte superior da página de Configuração.
  5. Executar o pipeline novamente. Suas dependências devem ser instaladas durante a implantação.

Disparar uma execução de pipeline

Para disparar uma execução de pipeline, confirme uma alteração no repositório. Por exemplo, você pode adicionar um novo recurso ao aplicativo ou atualizar as dependências do aplicativo.

  1. Acesse o seu repositório GitHub.
  2. Faça uma alteração no código, como alterar o título do aplicativo.
  3. Confirme a alteração em seu repositório.
  4. Vá para o pipeline e verifique se uma nova execução foi criada.
  5. Quando a execução estiver concluída, verifique se a nova compilação foi implantada em seu aplicativo Web.
    1. No portal do Azure, vá para seu aplicativo web.
    2. Selecione Centro de Implantação e selecione a guia Logs.
    3. Verifique se a nova implantação está listada.

Considerações para Django

Você pode usar o Azure Pipelines para implantar aplicativos Django no Serviço de Aplicativo do Azure no Linux se estiver usando um banco de dados separado. Você não pode usar um banco de dados SQLite porque o Serviço de Aplicativo bloqueia o arquivo db.sqlite3, impedindo leituras e gravações. Esse comportamento não afeta um banco de dados externo.

Conforme descrito em Configurar o aplicativo Python no Serviço de Aplicativo – processo de inicialização do contêiner, o Serviço de Aplicativo procura automaticamente um arquivo wsgi.py no código do aplicativo, que normalmente contém o objeto do aplicativo. Se você quiser personalizar o comando de inicialização de alguma forma, use o parâmetro startUpCommand na etapa AzureWebApp@1 do arquivo de pipeline YAML, conforme descrito na seção anterior.

Ao usar o Django, normalmente convém migrar os modelos de dados usando manage.py migrate depois de implantar o código do aplicativo. Você pode adicionar startUpCommand com um script pós-implantação para esta finalidade: Por exemplo, aqui está a propriedade startUpCommand na tarefa AzureWebApp@1.

  - task: AzureWebApp@1
      displayName: 'Deploy Azure Web App : $(webAppName)'
      inputs:
        azureSubscription: $(azureServiceConnectionId)
        appName: $(webAppName)
        package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
        startUpCommand: 'python manage.py migrate'

Executar testes no agente de build

Como parte do processo de compilação, convém executar testes no código do aplicativo. Os testes são executados no agente de compilação, portanto, você precisa instalar suas dependências em um ambiente virtual no agente de compilação. Após a execução dos testes, exclua o ambiente virtual antes de criar o arquivo .zip para implantação. Os elementos de script a seguir ilustram esse processo. Coloque-os antes da tarefa ArchiveFiles@2 no arquivo azure-pipelines.yml. Para obter mais informações, confira Executar scripts multiplataforma.

# The | symbol is a continuation character, indicating a multi-line script.
# A single-line script can immediately follow "- script:".
- script: |
    python -m venv .env
    source .env/bin/activate
    pip install setuptools
    pip install -r requirements.txt

  # The displayName shows in the pipeline UI when a build runs
  displayName: 'Install dependencies on build agent'

- script: |
    # Put commands to run tests here
    displayName: 'Run tests'

- script: |
    echo Deleting .env
    deactivate
    rm -rf .env
  displayName: 'Remove .env before zip'

Você também pode usar uma tarefa como PublishTestResults@2 para publicar os resultados do teste em seu pipeline. Para obter mais informações, confira Criar aplicativos Python – Executar testes.

Limpar os recursos

Para evitar incorrer em cobranças nos recursos do Azure criados neste tutorial:

  • Exclua o projeto que você criou. A exclusão do projeto exclui o pipeline e a conexão de serviço.

  • Exclua o grupo de recursos do Azure que contém o Serviço de Aplicativo e o Plano do Serviço de Aplicativo. No portal do Azure, acesse o grupo de recursos, selecione Excluir grupo de recursos e siga as solicitações.

  • Exclua a conta de armazenamento que mantém o sistema de arquivos do Cloud Shell. Feche o Cloud Shell e vá para o grupo de recursos que começa com cloud-shell-storage-, selecione Excluir grupo de recursos e siga as solicitações.

Próximas etapas