Creación e implementación de una aplicación web de Django en Azure con una identidad administrada asignada por el usuario
En este tutorial se implementa una aplicación web Django en Azure App Service. La aplicación web utiliza una identidad administrada asignada por el usuario (conexiones sin contraseña) con control de acceso basado en roles de Azure para acceder a los recursos Azure Storage y Azure Database for PostgreSQL - Flexible Server. El código utiliza la clase DefaultAzureCredential de la biblioteca de clientes Azure Identity para Python. La clase DefaultAzureCredential
detecta automáticamente que existe una identidad administrada para el App Service y la utiliza para acceder a otros recursos de Azure.
En este tutorial, creará una identidad administrada asignada por el usuario y se asigna al App Service para que pueda acceder a la base de datos y a los recursos de la cuenta de almacenamiento. Para ver un ejemplo de uso de una identidad administrada asignada por el sistema, consulte Creación e implementación de una aplicación web Flask Python en Azure con una identidad administrada asignada por el sistema. Las identidades administradas asignadas por el usuario se recomiendan porque pueden ser usadas por varios recursos y sus ciclos de vida están desacoplados de los ciclos de vida de los recursos a los que están asociadas. Para obtener más información sobre las prácticas recomendadas para el uso de identidades administradas, consulte Recomendaciones de prácticas recomendadas para identidades administradas.
En este tutorial se muestra cómo implementar la aplicación web Python y crear recursos Azure utilizando la CLI de Azure. Los comandos de este tutorial están escritos para ejecutarse en un shell Bash. Puede ejecutar los comandos del tutorial en cualquier entorno Bash con la CLI instalada, como su entorno local o Azure Cloud Shell. Con algunas modificaciones —por ejemplo, estableciendo y usando variables de entorno—, puede ejecutar estos comandos en otros entornos como el shell de comandos de Windows.
Obtención de la aplicación de ejemplo
Use la aplicación de ejemplo de Django para seguir este tutorial. Descargue o clone la aplicación de ejemplo en su entorno de desarrollo.
Clonación del ejemplo.
git clone https://github.com/Azure-Samples/msdocs-django-web-app-managed-identity.git
Vaya a la carpeta de la aplicación.
cd msdocs-django-web-app-managed-identity
Examine el código de autenticación
La aplicación web de ejemplo necesita autenticarse en dos almacenes de datos diferentes:
- El servidor de almacenamiento blob de Azure, donde almacena y recupera las fotos enviadas por los revisores.
- Una base de datos Azure Database for PostgreSQL - Servidor Flexible donde almacena los restaurantes y las reseñas.
Usa DefaultAzureCredential para autenticarse en ambos almacenes de datos. Con DefaultAzureCredential
, la aplicación puede configurarse para ejecutarse bajo la identidad de diferentes principales de servicio, dependiendo del entorno en el que se esté ejecutando, sin realizar cambios en el código. Por ejemplo, en un entorno de desarrollo local, la aplicación puede ejecutarse con la identidad del desarrollador que ha iniciado sesión en la CLI de Azure, mientras que en Azure, como en este tutorial, puede ejecutarse con una identidad administrada asignada por el usuario.
En cualquier caso, el principal de seguridad bajo el que se ejecuta la aplicación debe tener un rol en cada recurso Azure que la aplicación utiliza que le permita realizar las acciones en el recurso que la aplicación requiere. En este tutorial, usará los comandos de la CLI de Azure para crear una identidad administrada asignada por el usuario y asignarla a su aplicación en Azure. A continuación, asigne manualmente a esa identidad las funciones adecuadas en su cuenta de almacenamiento Azure y en el servidor Azure Database for PostgreSQL. Por último, se establece la variable de entorno AZURE_CLIENT_ID
para su aplicación en Azure para configurar DefaultAzureCredential
y usar la identidad administrada.
Una vez configurada la identidad administrada asignada al usuario en su aplicación y su entorno de ejecución, y asignados los roles adecuados en los almacenes de datos, puede usar DefaultAzureCredential
para autenticarse con los recursos Azure necesarios.
El siguiente código se utiliza para crear un cliente de almacenamiento blob para subir fotos en ./restaurant_review/views.py
. Se proporciona una instancia de DefaultAzureCredential
al cliente, que usa para adquirir tokens de acceso para realizar operaciones en el almacenamiento de 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)
También se utiliza una instancia de DefaultAzureCredential
para obtener un token de acceso para Azure Database for PostgreSQL en ./azureproject/get_conn.py
. En este caso, el token se adquiere directamente llamando a get_token en la instancia de credenciales y pasándole el valor scope
apropiado. A continuación, el token se usa para establecer la contraseña en el URI de conexión PostgreSQL.
azure_credential = DefaultAzureCredential()
token = azure_credential.get_token("https://ossrdbms-aad.database.windows.net")
conf.settings.DATABASES['default']['PASSWORD'] = token.token
Para obtener más información sobre la autenticación de sus aplicaciones con los servicios Azure, consulte Autenticación de aplicaciones Python en los servicios Azure mediante el SDK de Azure para Python. Para obtener más información sobre DefaultAzureCredential
, incluido cómo personalizar la cadena de credenciales que evalúa para su entorno, consulte Introducción a DefaultAzureCredential.
Crear un servidor flexible Azure PostgreSQL
Configure las variables de entorno necesarias para el 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
La
ADMIN_PW
debe contener entre 8 y 128 caracteres de tres de las siguientes categorías: Letras del alfabeto inglés mayúsculas y minúsculas, números y caracteres no alfanuméricos. Al crear nombres de usuario o contraseñas, no use el carácter$
. Más adelante creará variables de entorno con estos valores, donde el carácter$
tiene un significado especial dentro del contenedor de Linux que se usa para ejecutar aplicaciones de Python.Para crear un grupo de recursos, use el comando az group create.
az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
Cree un servidor flexible PostgreSQL con el comando az postgres flexible-server create. (Este comando y los siguientes usan el carácter de continuación de línea de Bash Shell ('\'). Cambie el carácter de continuación de línea para otros 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
El sku-name es el nombre del nivel de precios y de la configuración informática. Para más información, consulte los precios de Azure Database for PostgreSQL. Para enumerar las SKU disponibles, use
az postgres flexible-server list-skus --location $LOCATION
.Agregue su cuenta Azure como administrador de Microsoft Entra para el servidor con el 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
Configure una regla de cortafuegos en su servidor con el comando az postgres flexible-server firewall-rule create. Esta regla permite el acceso de su entorno local para conectarse al servidor. (Si usa Azure Cloud Shell, puede omitir este paso).
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 cualquier herramienta o sitio web que muestre su dirección IP para sustituir
<your IP>
en el comando. Por ejemplo, puede utilizar el sitio web ¿Cuál es mi dirección IP?.Cree una base de datos denominada
restaurant
mediante el 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;'
Creación de un Azure App Service e implementación del código
Ejecute estos comandos en la carpeta raíz de la aplicación de ejemplo para crear un servicio de aplicación e implementar el código en él.
Cree un servicio de aplicación con el comando az webapp up.
az webapp up \ --resource-group $RESOURCE_GROUP_NAME \ --location $LOCATION \ --name $APP_SERVICE_NAME \ --runtime PYTHON:3.9 \ --sku B1
El sku define el tamaño (CPU, memoria) y el coste del plan de App Service. El plan de servicio B1 (Básico) incurre en un pequeño coste en su suscripción Azure. Para obtener una lista completa de los planes de App Service, vea la página Precios de App Service.
Configure App Service para usar start.sh en el repositorio de ejemplo con el comando az webapp config set.
az webapp config set \ --resource-group $RESOURCE_GROUP_NAME \ --name $APP_SERVICE_NAME \ --startup-file "start.sh"
Creación de una cuenta de almacenamiento y un contenedor
La aplicación de ejemplo almacena las fotos enviadas por los revisores como blobs en Azure Storage.
Cuando un usuario envía una foto con su reseña, la app de ejemplo escribe la imagen en el contenedor mediante la identidad administrada y
DefaultAzureCredential
para acceder a la cuenta de almacenamiento.Cuando un usuario consulta las reseñas de un restaurante, la aplicación devuelve un enlace a la foto en el Blob Storage para cada reseña que tenga una asociada. Para que el navegador muestre la foto, debe poder acceder a ella en su cuenta de almacenamiento. Los datos blob deben estar disponibles para su lectura pública a través de un acceso anónimo (no autenticado).
En esta sección, creará una cuenta de almacenamiento y un contenedor que permita el acceso público de lectura a los blobs del contenedor. En secciones posteriores, se crea una identidad administrada asignada por el usuario y se configura para escribir blobs en la cuenta de almacenamiento.
Use el comando az storage create para crear una cuenta de almacenamiento.
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
Cree un contenedor llamado fotos en la cuenta de almacenamiento con el comando az storage container create.
az storage container create \ --account-name $STORAGE_ACCOUNT_NAME \ --name photos \ --public-access blob \ --auth-mode login
Nota:
Si el comando falla, por ejemplo, si obtiene un error que indica que la solicitud puede estar bloqueada por las reglas de red de la cuenta de almacenamiento, introduzca el siguiente comando para asegurarse de que su cuenta de usuario Azure tiene asignado un rol Azure con permiso para crear un contenedor.
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 obtener más información, consulte Inicio rápido: Creación, descarga y listados de blobs con Azure CLI. Tenga en cuenta que varios roles de Azure le permiten crear contenedores en una cuenta de almacenamiento, incluidos "Propietario", "Colaborador", "Propietario de datos de bloques de almacenamiento" y "Colaborador de datos de bloques de almacenamiento".
Creación de una identidad administrada asignada por el usuario
Cree una identidad administrada asignada por el usuario y asígnela al App Service. La identidad administrada se usa para acceder a la base de datos y a la cuenta de almacenamiento.
Use el comando az identity create para crear una identidad administrada asignada por el usuario y enviar el ID de cliente a una variable para su uso posterior.
UA_CLIENT_ID=$(az identity create --name $UA_NAME --resource-group $RESOURCE_GROUP_NAME --query clientId --output tsv) echo $UA_CLIENT_ID
Use el comando az account show para obtener su ID de suscripción y enviarlo a una variable que pueda utilizarse para construir el ID de recurso de la identidad administrada.
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
Asigne la identidad administrada al App Service con el 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
Cree la configuración de la aplicación App Service que contiene el ID de cliente de la identidad administrada y otra información de configuración con el 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
La aplicación de ejemplo usa variables de entorno (configuración de la aplicación) para definir la información de conexión para la base de datos y la cuenta de almacenamiento, pero estas variables no incluyen contraseñas. En su lugar, la autenticación se realiza sin contraseña con DefaultAzureCredential
.
El código de la aplicación de ejemplo utiliza el constructor de clase DefaultAzureCredential
sin pasar el ID de cliente de identidad administrada asignado por el usuario al constructor. En este escenario, la alternativa es comprobar la variable de entorno AZURE_CLIENT_ID
, que se establece como una configuración de la aplicación.
Si la variable de entorno AZURE_CLIENT_ID
no existe, se usa la identidad administrada asignada por el sistema si está configurada. Para más información, consulte Introducing DefaultAzureCredential.
Creación de roles para la identidad administrada
En esta sección, se crean asignaciones de funciones para la identidad administrada con el fin de permitir el acceso a la cuenta de almacenamiento y a la base de datos.
Cree una asignación de roles para la identidad administrada para permitir el acceso a la cuenta de almacenamiento con el 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"
El comando especifica el ámbito de la asignación de funciones al grupo de recursos. Para más información, consulte Comprender la asignación de roles.
Use el comando az postgres flexible-server execute para conectarse a la base de datos Postgres y ejecutar los mismos comandos para asignar funciones a la identidad administrada.
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);"
Si tiene problemas para ejecutar el comando, asegúrese de haber añadido su cuenta de usuario como administrador de Microsoft Entra para el servidor PosgreSQL y de haber permitido el acceso a su dirección IP en las reglas del cortafuegos. Para obtener más información, consulte la sección Crear un servidor Azure PostgreSQL flexible.
Prueba de la aplicación web Python en Azure
La aplicación Python de ejemplo utiliza el paquete azure.identity y su clase DefaultAzureCredential
. Cuando la app se ejecuta en Azure, DefaultAzureCredential
detecta automáticamente si existe una identidad administrada para el App Service y, si es así, la usa para acceder a otros recursos de Azure (almacenamiento y PostgreSQL en este caso). No es necesario proporcionar claves de almacenamiento, certificados o credenciales al App Service para acceder a estos recursos.
Vaya a la aplicación implementada en la dirección URL
http://$APP_SERVICE_NAME.azurewebsites.net
.La aplicación puede tardar uno o dos minutos en iniciarse. Si ve una página de aplicación predeterminada que no es la página de aplicación de muestra predeterminada, espere un minuto y actualice el navegador.
Pruebe la funcionalidad de la aplicación de ejemplo y añada un restaurante y algunas reseñas con fotos del restaurante.
La información del restaurante y las reseñas se almacenan en Azure Database for PostgreSQL y las fotos se almacenan en Azure Storage. He aquí una captura de pantalla de ejemplo:
Limpiar
En este tutorial, todos los recursos Azure se crearon en el mismo grupo de recursos. Eliminar el grupo de recursos con el comando az group delete elimina todos los recursos del grupo de recursos y es la forma más rápida de eliminar todos los recursos de Azure utilizados para su app.
az group delete --name $RESOURCE_GROUP_NAME
Opcionalmente, puede agregar el argumento --no-wait
para permitir que el comando devuelva antes de que se complete la operación.