Partilhar via


Criar e implantar um aplicativo Web Flask Python no Azure com identidade gerenciada atribuída ao sistema

Neste tutorial, desenvolve o código Python Flask para criar e implementar uma aplicação web que corre no Serviço de Aplicações do Azure. O aplicativo Web utiliza a sua identidade gerida (ligações sem necessidade de palavra-passe) com o controlo de acesso baseado em função do Azure para aceder aos recursos do Armazenamento do Azure e do Banco de Dados Azure para PostgreSQL - Servidor Flexível. O código utiliza a classe DefaultAzureCredential da biblioteca do cliente Azure Identity para Python. A classe DefaultAzureCredential deteta automaticamente que existe uma identidade gerida para o App Service e a usa para aceder a outros recursos do Azure.

Você pode configurar conexões sem senha para serviços do Azure usando o Service Connector ou pode configurá-las manualmente. Este tutorial mostra como usar o Service Connector. Para obter mais informações sobre ligações sem palavra-passe, consulte Ligações sem palavra-passe para serviços Azure. Para obter informações sobre o Service Connector, consulte a documentação do Service Connector.

Este tutorial mostra como criar e implantar um aplicativo Web Python usando a CLI do Azure. Os comandos neste tutorial são escritos para serem executados em um shell Bash. Você pode executar os comandos do tutorial em qualquer ambiente Bash com a CLI instalada, como seu ambiente local ou o Azure Cloud Shell. Com alguma modificação -- por exemplo, definindo e usando variáveis de ambiente -- você pode executar esses comandos em outros ambientes, como o shell de comando do Windows. Para obter exemplos de como usar uma identidade gerida atribuída pelo utilizador, consulte Criar e implantar uma aplicação Web Django no Azure com uma identidade gerida atribuída pelo utilizador.

Obter a aplicação de exemplo

Um aplicativo Python de exemplo usando a estrutura Flask está disponível para ajudá-lo a acompanhar este tutorial. Transfira ou clone uma das aplicações de exemplo para a estação de trabalho local.

  1. Clone o exemplo em uma sessão do Azure Cloud Shell.

    git clone https://github.com/Azure-Samples/msdocs-flask-web-app-managed-identity.git
    
  2. Navegue até a pasta do aplicativo.

    cd msdocs-flask-web-app-managed-identity
    

Examinar o código de autenticação

O aplicativo Web de exemplo precisa se autenticar em dois armazenamentos de dados diferentes:

  • Servidor de armazenamento de blob do Azure onde armazena e recupera fotos enviadas pelos revisores.
  • Um Banco de Dados do Azure para PostgreSQL - Banco de dados de Servidor Flexível onde armazena restaurantes e avaliações.

Ele usa DefaultAzureCredential para autenticar em ambos os armazenamentos de dados. Com DefaultAzureCredential, a aplicação pode ser configurada para executar sob a identidade de diferentes principais de serviço, dependendo do ambiente em que está a funcionar, sem necessidade de alterar o código. Por exemplo, em um ambiente de desenvolvimento local, o aplicativo pode ser executado sob a identidade do desenvolvedor conectado à CLI do Azure, enquanto no Azure, como neste tutorial, ele pode ser executado sob sua identidade gerenciada atribuída ao sistema.

Em ambos os casos, a entidade de segurança na qual o aplicativo é executado deve ter uma função em cada recurso do Azure que o aplicativo usa que lhe permita executar as ações no recurso que o aplicativo exige. Neste tutorial, você usa conectores de serviço para habilitar automaticamente a identidade gerenciada atribuída ao sistema em seu aplicativo no Azure e para atribuir a essa identidade funções apropriadas em sua conta de armazenamento do Azure e no Banco de Dados do Azure para servidor PostgreSQL.

Depois que a identidade gerenciada atribuída ao sistema for habilitada e as funções apropriadas forem atribuídas nos armazenamentos de dados, você poderá usar DefaultAzureCredential para autenticar com os recursos necessários do Azure.

O código a seguir é usado para criar um cliente de armazenamento de blob para carregar fotos em app.py. Uma instância de DefaultAzureCredential é fornecida ao cliente, que a utiliza para adquirir tokens de acesso e executar operações no armazenamento do Azure.

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

azure_credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
    account_url=account_url,
    credential=azure_credential)

Uma instância de DefaultAzureCredential também é utilizada para obter um token de acesso para a base de dados do Azure para PostgreSQL em ./azureproject/get_conn.py. Nesse caso, o token é adquirido diretamente chamando get_token na instância de credencial e passando-lhe o valor apropriado scope. O token é então usado no lugar da palavra-passe no URI de conexão PostgreSQL devolvido ao solicitante.

azure_credential = DefaultAzureCredential()
token = azure_credential.get_token("https://ossrdbms-aad.database.windows.net")
conn = str(current_app.config.get('DATABASE_URI')).replace('PASSWORDORTOKEN', token.token)

Para saber mais sobre como autenticar as suas aplicações com os serviços do Azure, consulte Autenticar aplicações Python nos serviços do Azure usando o Azure SDK para Python. Para saber mais sobre DefaultAzureCredential, incluindo como personalizar a cadeia de credenciais que avalia para o seu ambiente, consulte a visão geral do DefaultAzureCredential.

Criar um servidor PostgreSQL do Azure

  1. Configure as variáveis de ambiente necessárias para o tutorial.

    LOCATION="eastus"
    RAND_ID=$RANDOM
    RESOURCE_GROUP_NAME="msdocs-mi-web-app"
    APP_SERVICE_NAME="msdocs-mi-web-$RAND_ID"
    DB_SERVER_NAME="msdocs-mi-postgres-$RAND_ID"
    ADMIN_USER="demoadmin"
    ADMIN_PW="ChAnG33#ThsPssWD$RAND_ID"
    

    Importante

    O ADMIN_PW deve conter de 8 a 128 caracteres de três das seguintes categorias: letras maiúsculas em inglês, letras minúsculas em inglês, números e caracteres não alfanuméricos. Ao criar nomes de utilizador ou senhas não use o $ caractere. Mais tarde, cria variáveis de ambiente com esses valores, onde o caractere $ tem um significado especial dentro do contêiner Linux usado para executar aplicações Python.

  2. Crie um grupo de recursos com o comando az group create.

    az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
    
  3. Crie um servidor PostgreSQL com o comando `az postgres flexible-server create`. (Este e os comandos subsequentes usam o caractere de continuação de linha para Bash Shell ('\'). Altere o caractere de continuação de linha para seu shell, se necessário.)

    az postgres flexible-server create \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $DB_SERVER_NAME \
      --location $LOCATION \
      --admin-user $ADMIN_USER \
      --admin-password $ADMIN_PW \
      --sku-name Standard_D2ds_v4
    

    O sku-name é o nome do nível de preços e da configuração de computação. Para obter mais informações, consulte os preços do Azure Base de Dados para PostgreSQL. Para listar SKUs disponíveis, use az postgres flexible-server list-skus --location $LOCATION.

  4. Crie uma base de dados nomeada restaurant usando o comando az postgres flexible-server execute.

    az postgres flexible-server execute \
      --name $DB_SERVER_NAME \
      --admin-user $ADMIN_USER \
      --admin-password $ADMIN_PW \
      --database-name postgres \
      --querytext 'create database restaurant;'
    

Criar um Serviço de Aplicativo do Azure e implantar o código

  1. Crie um serviço de aplicação usando o comando az webapp up.

    az webapp up \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --runtime PYTHON:3.9 \
      --sku B1
    

    O sku define o tamanho (CPU, memória) e o custo do plano de serviço da aplicação. O plano de serviço B1 (Básico) incorre em um pequeno custo em sua assinatura do Azure. Para obter uma lista completa dos planos do App Service, consulte a página de preços na App Service.

  2. Configurar o App Service para usar o start.sh no repositório com o comando az webapp config set.

    az webapp config set \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --startup-file "start.sh"
    

Criar conectores sem senha para recursos do Azure

Os comandos do Service Connector configuram o Armazenamento do Azure e os recursos do Banco de Dados do Azure para PostgreSQL para usarem identidade gerida e controlo de acesso baseado em funções do Azure. Os comandos criam configurações de aplicativo no Serviço de Aplicativo que conectam seu aplicativo Web a esses recursos. A saída dos comandos lista as ações do conector de serviço tomadas para ativar a funcionalidade sem palavra-passe.

  1. Adicione um conector de serviço PostgreSQL com o comando az webapp connection create postgres-flexible. A identidade gerenciada atribuída ao sistema é usada para autenticar o aplicativo Web no recurso de destino, o PostgreSQL, neste caso.

    az webapp connection create postgres-flexible \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --target-resource-group $RESOURCE_GROUP_NAME \
      --server $DB_SERVER_NAME \
      --database restaurant \
      --client-type python \
      --system-identity
    
  2. Adicione um conector de serviço de armazenamento com o comando az webapp connection create storage-blob.

    Este comando também adiciona uma conta de armazenamento e adiciona o aplicativo Web com a função Storage Blob Data Contributor à conta de armazenamento.

    STORAGE_ACCOUNT_URL=$(az webapp connection create storage-blob \
      --new true \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --target-resource-group $RESOURCE_GROUP_NAME \
      --client-type python \
      --system-identity \
      --query configurations[].value \
      --output tsv)
    STORAGE_ACCOUNT_NAME=$(cut -d . -f1 <<< $(cut -d / -f3 <<< $STORAGE_ACCOUNT_URL))
    

Criar um contêiner na conta de armazenamento

O aplicativo Python de exemplo armazena fotos enviadas pelos revisores como blobs em um contêiner em sua conta de armazenamento.

  • Quando um usuário envia uma foto com sua revisão, o aplicativo de exemplo grava a imagem no contêiner usando sua identidade gerenciada atribuída pelo sistema para autenticação e autorização. Você configurou essa funcionalidade na última seção.

  • Quando um usuário visualiza as avaliações de um restaurante, o aplicativo retorna um link para a foto no armazenamento de blob para cada avaliação associada a ela. Para que o navegador exiba a foto, ele deve ser capaz de acessá-la em sua conta de armazenamento. Os dados de blob devem estar disponíveis para leitura pública através de acesso anônimo (não autenticado).

Para aumentar a segurança, as contas de armazenamento são criadas com o acesso anônimo aos dados de blob desativado por padrão. Nesta seção, você habilita o acesso de leitura anônimo em sua conta de armazenamento e, em seguida, cria um contêiner chamado fotos que fornece acesso público (anônimo) a seus blobs.

  1. Atualizar a conta de armazenamento para permitir acesso de leitura anónimo a blobs com o comando az storage account update.

    az storage account update \
      --name $STORAGE_ACCOUNT_NAME \
      --resource-group $RESOURCE_GROUP_NAME \
      --allow-blob-public-access true
    

    Habilitar o acesso anônimo na conta de armazenamento não afeta o acesso para blobs individuais. Você deve habilitar explicitamente o acesso público a blobs no nível do contêiner.

  2. Crie um contentor chamado fotos na conta de armazenamento com o comando az storage container create. Permita acesso de leitura anônima (público) a blobs no contêiner recém-criado.

    az storage container create \
      --account-name $STORAGE_ACCOUNT_NAME \
      --name photos \
      --public-access blob \
      --account-key $(az storage account keys list --account-name $STORAGE_ACCOUNT_NAME \
          --query [0].value --output tsv) 
    

    Nota

    Para maior brevidade, este comando usa a chave da conta de armazenamento para efetuar a autorização com a conta de armazenamento. Para a maioria dos cenários, a abordagem recomendada da Microsoft é usar as funções Microsoft Entra ID e Azure (RBAC). Para um conjunto rápido de instruções, consulte Guia de início rápido: Criar, transferir e listar blobs com a CLI do Azure. Observe que várias funções do Azure permitem que você crie contêineres em uma conta de armazenamento, incluindo "Proprietário", "Colaborador", "Proprietário de Dados de Blob de Armazenamento" e "Colaborador de Dados de Blob de Armazenamento".

Para saber mais sobre o acesso de leitura anónima a dados de blob, consulte Configuração de acesso de leitura anónima para recipientes e blobs.

Testar o aplicativo Web Python no Azure

O aplicativo Python de exemplo usa o pacote azure.identity e a sua classe DefaultAzureCredential. Quando o aplicativo está sendo executado no Azure, DefaultAzureCredential deteta de forma automática se existe uma identidade gerenciada para o Serviço de Aplicativo e, em caso afirmativo, usa-a para acessar outros recursos do Azure (armazenamento e PostgreSQL, neste caso). Não há necessidade de fornecer chaves de armazenamento, certificados ou credenciais ao Serviço de Aplicativo para acessar esses recursos.

  1. Navegue até a aplicação implementada no URL http://$APP_SERVICE_NAME.azurewebsites.net.

    Pode levar um ou dois minutos para o aplicativo iniciar. Se vir uma página de aplicação predefinida que não seja a página de aplicação de exemplo predefinida, aguarde um minuto e atualize o browser.

  2. Teste a funcionalidade do aplicativo de exemplo adicionando um restaurante e algumas avaliações com fotos do restaurante.

    As informações de restaurante e revisão são armazenadas no Banco de Dados do Azure para PostgreSQL e as fotos são armazenadas no Armazenamento do Azure. Aqui está um exemplo de captura de tela:

    Captura de ecrã da aplicação de exemplo que mostra a funcionalidade de revisão de restaurantes utilizando o Serviço de Aplicações do Azure, a Base de Dados PostgreSQL do Azure e o Armazenamento do Azure.

Limpeza

Neste tutorial, todos os recursos do Azure foram criados no mesmo grupo de recursos. Remover o grupo de recursos com o comando az group delete elimina todos os recursos no grupo de recursos e é a maneira mais rápida de remover todos os recursos do Azure utilizados para a sua aplicação.

az group delete  --name $RESOURCE_GROUP_NAME 

Opcionalmente, pode adicionar o argumento --no-wait para permitir que o comando retorne antes de a operação ser concluída.

Próximos passos

  • Criar e implementar uma aplicação web Django no Azure com uma identidade gerida atribuída pelo utilizador

  • Implantar uma aplicação web em Python (Django ou Flask) com PostgreSQL no Azure App Service.