Compartilhar via


Criar e implantar um aplicativo Web Django no Azure com uma identidade gerenciada atribuída pelo usuário

Neste tutorial, você vai implantar um aplicativo Web do Django no Serviço de Aplicativo do Azure. O aplicativo Web usa uma identidade gerenciada atribuída pelo usuário (conexões sem senha) com controle de acesso baseado em função do Azure para acessar os recursos Armazenamento do Azure e Banco de Dados do Azure para PostgreSQL – Servidor Flexível. O código usa a classe DefaultAzureCredential da biblioteca de clientes do Azure Identity para Python. A classe DefaultAzureCredential detecta automaticamente que existe uma identidade gerenciada para o Serviço de Aplicativo e a usa para acessar outros recursos do Azure.

Neste tutorial, você vai criar uma identidade gerenciada atribuída pelo usuário e atribui-la ao Serviço de Aplicativo para que ele possa acessar os recursos do banco de dados e da conta de armazenamento. Para obter um exemplo de como usar uma identidade gerenciada atribuída pelo sistema, consulte Criar e implantar um aplicativo Web Python do Flask no Azure com a identidade gerenciada atribuída pelo sistema. As identidades gerenciadas atribuídas pelo usuário são recomendadas porque podem ser usadas por vários recursos, e seus ciclos de vida são dissociados dos ciclos de vida dos recursos com os quais estão associadas. Para obter mais informações sobre as práticas recomendadas para usar identidades gerenciadas, consulte Recomendações de práticas recomendadas de identidade gerenciada.

Este tutorial mostra como implantar o aplicativo Web Python e criar recursos do Azure 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 algumas modificações, por exemplo, definindo e usando variáveis de ambiente, você pode executar esses comandos em outros ambientes, como o shell de comando do Windows.

Obter o aplicativo de exemplo

Use o aplicativo de exemplo do Django para acompanhar este tutorial. Baixe ou clone o aplicativo de exemplo para seu ambiente de desenvolvimento.

  1. Clone o exemplo.

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

    cd msdocs-django-web-app-managed-identity
    

Examinar o código de autenticação

O aplicativo Web de exemplo precisa ser autenticado em dois armazenamentos de dados diferentes:

  • Servidor de armazenamento de blobs do Azure onde ele armazena e recupera fotos enviadas por revisores.
  • Um Banco de Dados do Azure para PostgreSQL – Servidor Flexível onde ele armazena restaurantes e avaliações.

Ele usa DefaultAzureCredential para autenticar nos dois armazenamentos de dados. Com o DefaultAzureCredential, o aplicativo pode ser configurado para ser executado sob a identidade de diferentes entidades de serviço, dependendo do ambiente em que está sendo executado, sem fazer alterações no 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 uma identidade gerenciada atribuída pelo usuário.

Em ambos os casos, a entidade de segurança sob a qual o aplicativo é executado deve ter uma função em cada recurso do Azure que o aplicativo usa que permita executar as ações no recurso que o aplicativo exige. Neste tutorial, você vai usar comandos da CLI do Azure para criar uma identidade gerenciada atribuída pelo usuário e atribuí-la ao seu aplicativo no Azure. Em seguida, atribua manualmente essa identidade às funções apropriadas em sua conta de armazenamento do Azure e no servidor do Banco de Dados do Azure para PostgreSQL. Por fim, você vai definir a variável de ambiente AZURE_CLIENT_ID do seu aplicativo no Azure para configurar DefaultAzureCredential para usar a identidade gerenciada.

Depois que a identidade gerenciada atribuída pelo usuário for configurada no aplicativo e seu ambiente de runtime e receber as funções apropriadas 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 blobs para carregar fotos no ./restaurant_review/views.py. Uma instância de DefaultAzureCredential é fornecida ao cliente, que ele usa para adquirir tokens de acesso para 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 é usada para obter um token de acesso para o Banco de Dados do Azure para PostgreSQL no ./azureproject/get_conn.py. Nesse caso, o token é adquirido diretamente chamando get_token na instância de credencial e transmitindo o valor apropriado de scope. O token é usado para definir a senha no URI de conexão do PostgreSQL.

azure_credential = DefaultAzureCredential()
token = azure_credential.get_token("https://ossrdbms-aad.database.windows.net")
conf.settings.DATABASES['default']['PASSWORD'] = token.token

Para saber mais sobre como autenticar seus aplicativos com serviços do Azure, consulte Autenticar aplicativos Python para serviços do Azure usando o SDK do Azure para Python. Para saber mais sobre o DefaultAzureCredential, incluindo como personalizar a cadeia de credenciais que ele avalia para seu ambiente, consulte Visão geral do DefaultAzureCredential.

Criar um servidor flexível do 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"
    UA_NAME="UAManagedIdentityPythonTest$RAND_ID"
    

    Importante

    O ADMIN_PW precisa conter de 8 a 128 caracteres de três das seguintes categorias: letras maiúsculas, letras minúsculas, números e caracteres não alfanuméricos. Ao criar nomes de um ou senhas, não use o $ caractere. Posteriormente, você cria variáveis de ambiente com esses valores no qual o caractere $ tem um significado especial dentro do contêiner do Linux usado para executar aplicativos 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 flexível do PostgreSQL com o comando az postgres flexible-server create. (Este comando e os subsequentes usam o caractere de continuação de linha para o Shell Bash ('\'). Altere o caractere de continuação de linha para outros shells.

    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 \
      --active-directory-auth Enabled \
      --public-access 0.0.0.0
    

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

  4. Adicione sua conta do Azure como administrador do Microsoft Entra para o servidor com o comando az postgres flexible-server ad-admin create.

    ACCOUNT_EMAIL=$(az ad signed-in-user show --query userPrincipalName --output tsv)
    ACCOUNT_ID=$(az ad signed-in-user show --query id --output tsv)
    echo $ACCOUNT_EMAIL, $ACCOUNT_ID
    az postgres flexible-server ad-admin create \
      --resource-group $RESOURCE_GROUP_NAME \
      --server-name $DB_SERVER_NAME \
      --display-name $ACCOUNT_EMAIL \
      --object-id $ACCOUNT_ID \
      --type User
    
  5. Configure uma regra de firewall no servidor com o comando az postgres flexible-server firewall-rule create. Essa regra permite que o acesso ao ambiente local se conecte ao servidor. (Se estiver usando o Azure Cloud Shell, você poderá ignorar esta etapa.)

    IP_ADDRESS=<your IP>
    az postgres flexible-server firewall-rule create \
       --resource-group $RESOURCE_GROUP_NAME \
       --name $DB_SERVER_NAME \
       --rule-name AllowMyIP \
       --start-ip-address $IP_ADDRESS \
       --end-ip-address $IP_ADDRESS
    

    Use qualquer ferramenta ou site que mostre seu endereço IP para substituir <your IP> no comando. Por exemplo, você pode usar o site Qual é o meu endereço IP?.

  6. Crie um banco de dados chamado 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

Execute esses comandos na pasta raiz do aplicativo de exemplo para criar um Serviço de Aplicativo e implantar o código nele.

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

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

    O sku define o tamanho (CPU, memória) e o custo do Plano do Serviço de Aplicativo. O plano de serviço B1 (Básico) gera um pequeno custo em sua assinatura do Azure. Para obter uma lista completa dos planos do Serviço de Aplicativo, exiba a página de Preço do Serviço de Aplicativo.

  2. Configure o Serviço de Aplicativo para usar o start.sh no repositório de exemplo 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 uma conta e um contêiner de armazenamento

O aplicativo de exemplo armazena fotos enviadas por revisores como blobs no Armazenamento do Azure.

  • Quando um usuário envia uma foto com a revisão, o aplicativo de exemplo grava a imagem no contêiner usando a identidade gerenciada e DefaultAzureCredential para acessar a conta de armazenamento.

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

Nesta seção, você cria uma conta de armazenamento e um contêiner que permite acesso público de leitura a blobs no contêiner. Em seções posteriores, você vai criar uma identidade gerenciada atribuída pelo usuário e configurá-la para gravar blobs na conta de armazenamento.

  1. Use o comando az storage create para criar uma conta de armazenamento.

    STORAGE_ACCOUNT_NAME="msdocsstorage$RAND_ID"
    az storage account create \
      --name $STORAGE_ACCOUNT_NAME \
      --resource-group $RESOURCE_GROUP_NAME \
      --location $LOCATION \
      --sku Standard_LRS \
      --allow-blob-public-access true
    
  2. Crie um contêiner chamado photos na conta de armazenamento com o comando az storage container create.

    az storage container create \
      --account-name $STORAGE_ACCOUNT_NAME \
      --name photos \
      --public-access blob \
      --auth-mode login
    

    Observação

    Se o comando falhar, por exemplo, se você receber um erro indicando que a solicitação pode ser bloqueada pelas regras de rede da conta de armazenamento, insira o comando a seguir para garantir que sua conta de usuário do Azure tenha uma função do Azure atribuída com permissão para criar um contêiner.

    az role assignment create --role "Storage Blob Data Contributor" --assignee $ACCOUNT_EMAIL --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.Storage/storageAccounts/$STORAGE_ACCOUNT_NAME"
    

    Para obter mais informações, confira Guia de início rápido: Criar, baixar e listar blobs com a CLI do Azure. 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 do Blob de Armazenamento" e "Colaborador de Dados do Blob de Armazenamento".

Criar uma identidade gerenciada atribuída ao usuário

Crie uma identidade gerenciada atribuída pelo usuário e atribua-a ao Serviço de Aplicativo. A identidade gerenciada é usada para acessar o banco de dados e a conta de armazenamento.

  1. Use o comando az identity create para criar uma identidade gerenciada atribuída pelo usuário e gerar o ID do cliente para uma variável para uso posterior.

    UA_CLIENT_ID=$(az identity create --name $UA_NAME --resource-group $RESOURCE_GROUP_NAME --query clientId --output tsv)
    echo $UA_CLIENT_ID
    
  2. Use o comando az account show para obter o ID de assinatura e enviá-lo para uma variável que pode ser usada para construir o ID de recurso da identidade gerenciada.

    SUBSCRIPTION_ID=$(az account show --query id --output tsv)
    RESOURCE_ID="/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$UA_NAME"
    echo $RESOURCE_ID
    
  3. Atribua a identidade gerenciada ao Serviço de Aplicativo com o comando az webapp identity assign.

    export MSYS_NO_PATHCONV=1
    az webapp identity assign \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $APP_SERVICE_NAME \
        --identities $RESOURCE_ID
    
  4. Crie configurações do Serviço de Aplicativo que contenham o ID do cliente da identidade gerenciada e outras informações de configuração com o comando az webapp config appsettings set.

    az webapp config appsettings set \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --settings AZURE_CLIENT_ID=$UA_CLIENT_ID \
        STORAGE_ACCOUNT_NAME=$STORAGE_ACCOUNT_NAME \
        STORAGE_CONTAINER_NAME=photos \
        DBHOST=$DB_SERVER_NAME \
        DBNAME=restaurant \
        DBUSER=$UA_NAME
    

O aplicativo de exemplo usa variáveis de ambiente (configurações do aplicativo) para definir informações de conexão para o banco de dados e a conta de armazenamento, mas essas variáveis não incluem senhas. Em vez disso, a autenticação é feita sem senha com DefaultAzureCredential.

O código do aplicativo de exemplo usa o construtor de classe DefaultAzureCredential sem transmitir o ID do cliente de identidade gerenciada atribuído pelo usuário para o construtor. Nesse cenário, o fallback é verificar a variável de ambiente AZURE_CLIENT_ID, que você define como uma configuração do aplicativo.

Se a variável de ambiente AZURE_CLIENT_ID não existir, a identidade gerenciada atribuída pelo sistema será usada se estiver configurada. Para obter mais informações, confira Introdução a DefaultAzureCredential.

Criar funções para a identidade gerenciada

Nesta seção, você vai criar atribuições de função para a identidade gerenciada para habilitar o acesso à conta de armazenamento e ao banco de dados.

  1. Crie uma atribuição de função para a identidade gerenciada para habilitar o acesso à conta de armazenamento com o comando az role assignment create.

    export MSYS_NO_PATHCONV=1
    az role assignment create \
    --assignee $UA_CLIENT_ID \
    --role "Storage Blob Data Contributor" \
    --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCE_GROUP_NAME"
    

    O comando especifica o escopo da atribuição de função ao grupo de recursos. Para obter mais informações, confira Compreender atribuições de função.

  2. Use o comando az postgres flexible-server execute para se conectar ao banco de dados Postgres e executar os mesmos comandos para atribuir funções à identidade gerenciada.

    ACCOUNT_EMAIL_TOKEN=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken)
    az postgres flexible-server execute \
      --name $DB_SERVER_NAME \
      --admin-user $ACCOUNT_EMAIL \
      --admin-password $ACCOUNT_EMAIL_TOKEN \
      --database-name postgres \
      --querytext "select * from pgaadauth_create_principal('"$UA_NAME"', false, false);select * from pgaadauth_list_principals(false);"
    

    Se você tiver problemas para executar o comando, adicione sua conta de usuário como administrador do Microsoft Entra para o servidor PosgreSQL e permita o acesso ao seu endereço IP nas regras de firewall. Para obter mais informações, consulte a seção Criar um servidor flexível do Azure PostgreSQL.

Testar o aplicativo Web Python no Azure

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

  1. Navegue até o aplicativo implantado no URL http://$APP_SERVICE_NAME.azurewebsites.net.

    Pode levar um ou dois minutos para o aplicativo iniciar. Se você vir uma página de aplicativo padrão que não seja a página de aplicativo de exemplo padrão, aguarde um minuto e atualize o navegador.

  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 avaliaçã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 tela do aplicativo de exemplo mostrando a funcionalidade de avaliação de restaurante usando o Serviço de Aplicativo do Azure, o Banco de Dados PostgreSQL do Azure e o Armazenamento do Azure.

Limpar

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 remove todos os recursos do grupo de recursos e é a maneira mais rápida de remover todos os recursos do Azure usados para seu aplicativo.

az group delete  --name $RESOURCE_GROUP_NAME 

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

Próximas etapas