Compartir vía


Ejemplo: Acceso a Azure Storage con las bibliotecas de Azure para Python

En este artículo, aprenderá a usar las bibliotecas cliente de Azure SDK en el código de la aplicación de Python para cargar un archivo en un contenedor de Azure Blob Storage. En el artículo se da por supuesto que ha creado los recursos que se muestran en Ejemplo: Creación de Azure Storage.

Todos los comandos de este artículo funcionan igual en el bash de Linux o macOS y en los shells de comandos de Windows, a menos que se indique lo contrario.

1. Configuración del entorno de desarrollo local

Si aún no lo ha hecho, configure un entorno en el que pueda ejecutar este código. Estas son algunas opciones:

2. Instalación de paquetes de biblioteca

En el archivo requirements.txt, agregue líneas para los paquetes de biblioteca cliente que necesita y guarde el archivo.

azure-storage-blob
azure-identity

Luego, en el terminal o el símbolo del sistema, instale los requisitos.

pip install -r requirements.txt

3. Creación de un archivo para cargar

Cree un archivo de origen denominado sample-source.txt. Este nombre de archivo es lo que el código espera.

Hello there, Azure Storage. I'm a friendly file ready to be stored in a blob.

4. Uso de Blob Storage en el código de la aplicación

Esta sección demuestra dos formas de acceder a los datos en el contenedor blob que creaste en Ejemplo: Creación de Azure Storage. Para acceder a los datos del contenedor de blobs, su aplicación debe ser capaz de autenticarse con Azure y estar autorizada para acceder a los datos del contenedor. Esta sección presenta dos formas de hacerlo:

  • El método sin contraseña (recomendado) autentica la app usando DefaultAzureCredential. DefaultAzureCredential es una credencial encadenada que puede autenticar una aplicación (o un usuario) usando una secuencia de credenciales diferentes, incluidas las credenciales de la herramienta de desarrollo, las principales del servicio de aplicaciones y las identidades gestionadas.

  • El método de Cadena de conexión usa una cadena de conexión para acceder directamente a la cuenta de almacenamiento.

Por las siguientes razones, entre otras, recomendamos usar el método sin contraseña siempre que sea posible:

  • Una cadena de conexión autentica al agente que se conecta con la cuenta de almacenamiento en lugar de con recursos individuales dentro de esa cuenta. En consecuencia, una cadena de conexión otorga una autorización más amplia de la que podría ser necesaria. Con DefaultAzureCredential puede conceder permisos más granulares y menos privilegiados sobre sus recursos de almacenamiento a la identidad bajo la que se ejecuta su aplicación usando Azure RBAC.

  • Una cadena de conexión contiene información de acceso en texto sin formato y, por lo tanto, presenta posibles vulnerabilidades si no está correctamente construida o protegida. Si dicha cadena de conexión quedara expuesta, podría usarse para acceder a una amplia variedad de recursos dentro de la cuenta de almacenamiento.

  • Una cadena de conexión normalmente se almacena en una variable de entorno, lo que la hace vulnerable si un atacante obtiene acceso a su entorno. Muchos de los tipos de credenciales compatibles con DefaultAzureCredential no requieren almacenar secretos en su entorno.

DefaultAzureCredential es una cadena de credenciales preconfigurada. Está diseñada para admitir muchos entornos, junto con los flujos de autenticación y las herramientas de desarrollo más comunes. Una instancia de DefaultAzureCredential determina para qué tipos de credenciales intentar obtener un token basándose en una combinación de su entorno en tiempo de ejecución, el valor de ciertas variables de entorno bien conocidas y, opcionalmente, los parámetros pasados a su constructor.

En los siguientes pasos, se configura una entidad de seguridad de servicio de aplicación como identidad de la aplicación. Las entidades de seguridad del servicio de aplicaciones son adecuadas para su uso tanto durante el desarrollo local como para aplicaciones alojadas en las instalaciones. Para configurar DefaultAzureCredential para usar la entidad de seguridad del servicio de aplicaciones, debe establecer las siguientes variables de entorno: AZURE_CLIENT_ID, AZURE_TENANT_ID y AZURE_CLIENT_SECRET.

Observe que se ha configurado un secreto de cliente. Esto es necesario para una entidad de seguridad de servicio de aplicación, pero, dependiendo de su escenario, también puede configurar DefaultAzureCredential para usar de credenciales que no requieran establecer un secreto o contraseña en una variable de entorno.

Por ejemplo, en el desarrollo local, si DefaultAzureCredential no puede obtener un token usando variables de entorno configuradas, se intenta obtener uno usando el usuario (ya) registrado en herramientas de desarrollo como Azure CLI; para una aplicación alojada en Azure, se puede configurar DefaultAzureCredential para usar una identidad administrada. En todos los casos, el código de su aplicación sigue siendo el mismo, solo cambia la configuración y/o el entorno de ejecución.

  1. Cree un archivo llamado use_blob_auth.py con el código siguiente. Los pasos se explican en los comentarios.

    import os
    import uuid
    
    from azure.identity import DefaultAzureCredential
    
    # Import the client object from the SDK library
    from azure.storage.blob import BlobClient
    
    credential = DefaultAzureCredential()
    
    # Retrieve the storage blob service URL, which is of the form
    # https://<your-storage-account-name>.blob.core.windows.net/
    storage_url = os.environ["AZURE_STORAGE_BLOB_URL"]
    
    # Create the client object using the storage URL and the credential
    blob_client = BlobClient(
        storage_url,
        container_name="blob-container-01",
        blob_name=f"sample-blob-{str(uuid.uuid4())[0:5]}.txt",
        credential=credential,
    )
    
    # Open a local file and upload its contents to Blob Storage
    with open("./sample-source.txt", "rb") as data:
        blob_client.upload_blob(data)
        print(f"Uploaded sample-source.txt to {blob_client.url}")
    

    Vínculos de referencia:

  2. Cree una variable de entorno llamada AZURE_STORAGE_BLOB_URL:

    set AZURE_STORAGE_BLOB_URL=https://pythonazurestorage12345.blob.core.windows.net
    

    Reemplace "pythonazurestorage12345" por el nombre de su cuenta de almacenamiento.

    En este ejemplo solo se usa la variable de entorno AZURE_STORAGE_BLOB_URL. Las bibliotecas de Azure no la usan.

  3. Use el comando az ad sp create-for-rbac para crear una entidad de servicio nueva para la aplicación. El comando crea el registro de aplicación para la aplicación al mismo tiempo. Asigne a la entidad de servicio un nombre de su elección.

    az ad sp create-for-rbac --name <service-principal-name>
    

    El resultado de este comando tendrá un aspecto similar al siguiente. Anote estos valores o mantenga esta ventana abierta, ya que necesitará estos valores en el paso siguiente y no podrá volver a ver el valor de la contraseña (secreto del cliente). Sin embargo, si es necesario, se puede agregar una nueva contraseña posteriormente sin invalidar la entidad de servicio ni las contraseñas existentes.

    {
      "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
      "displayName": "<service-principal-name>",
      "password": "Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2",
      "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
    }
    

    Los comandos de la CLI de Azure se pueden ejecutar en Azure Cloud Shell o en una estación de trabajo que tenga la CLI de Azure instalada.

  4. Cree variables de entorno para la entidad de servicio de la aplicación:

    Cree las siguientes variables de entorno con los valores de la salida del comando anterior. Estas variables indican a DefaultAzureCredential que debe usar la entidad de servicio de la aplicación.

    • AZURE_CLIENT_ID → Valor del id. de la aplicación.
    • AZURE_TENANT_ID → Valor del id. de inquilino.
    • AZURE_CLIENT_SECRET → Contraseña o credencial generada para la aplicación.
    set AZURE_CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
    set AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
    set AZURE_CLIENT_SECRET=Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2
    
  5. Intente ejecutar el código (que produce un error de forma intencionada):

    python use_blob_auth.py
    
  6. Observe el error "Esta solicitud no está autorizada para realizar esta operación mediante este permiso". Este error es esperado, porque la entidad de servicio local que se está usando aún no tiene permiso para acceder al contenedor de blobs.

  7. Conceda permisos de Colaborador de Storage Blob Data en el contenedor blob al service principal usando el comando az role assignment create de Azure CLI:

    az role assignment create --assignee <AZURE_CLIENT_ID> \
        --role "Storage Blob Data Contributor" \
        --scope "/subscriptions/<AZURE_SUBSCRIPTION_ID>/resourceGroups/PythonAzureExample-Storage-rg/providers/Microsoft.Storage/storageAccounts/pythonazurestorage12345/blobServices/default/containers/blob-container-01"
    

    El argumento --assignee identifica la entidad de servicio. Reemplace el marcador de posición <AZURE_CLIENT_ID> por el identificador de aplicación de la entidad de servicio.

    El argumento --scope identifica dónde se aplica esta asignación de roles. En este ejemplo, concederá el rol "Colaborador de datos de blobs de almacenamiento" a la entidad de servicio para el contenedor específico denominado "blob-container-01".

    • Reemplace PythonAzureExample-Storage-rg y pythonazurestorage12345 por el grupo de recursos que contiene la cuenta de almacenamiento y el nombre exacto de la cuenta de almacenamiento. Además, ajuste el nombre del contenedor de blobs, si es necesario. Si usa un nombre incorrecto, aparecerá el error "No se puede realizar la operación solicitada en el recurso anidado. No se encontró el recurso primario 'pythonazurestorage12345'".

    • Reemplace el marcador de posición <AZURE_SUBSCRIPTION_ID> por su identificador de suscripción de Azure. (Puede ejecutar el comando az account show y obtener el identificador de suscripción de la propiedad id en la salida).

    Sugerencia

    Si el comando de asignación de roles devuelve un error "No se encontraron adaptadores de conexión" al usar el shell de Bash, intente establecer export MSYS_NO_PATHCONV=1 para evitar la traducción de rutas de acceso. Para más información, consulta esta propuesta.

  8. Espere un minuto o dos para que los permisos se propaguen y, después, vuelva a ejecutar el código para comprobar que ahora funciona. Si vuelve a ver el error de permisos, espere un poco más y vuelva a probar el código.

Para más información sobre las asignaciones de roles, consulte Incorporación o eliminación de asignaciones de roles de Azure mediante la CLI de Azure.

Importante

En los pasos anteriores, su aplicación se ejecutó bajo una entidad de seguridad de servicio de aplicación. Una entidad de seguridad de servicio de aplicación requiere un secreto de cliente en su configuración. Sin embargo, puede usar el mismo código para ejecutar la aplicación bajo diferentes tipos de credenciales que no requieren que configure explícitamente una contraseña o secreto en el entorno. Por ejemplo, durante el desarrollo, DefaultAzureCredential puede usar credenciales de la herramienta para desarrolladores como las credenciales que usa para iniciar sesión a través de la CLI de Azure; o bien, para las aplicaciones alojadas en Azure, puede usar una identidad administrada. Para obtener más información, consulte Autenticar aplicaciones Python en servicios Azure mediante el SDK de Azure para Python.

5. Comprobación de la creación de blobs

Después de ejecutar el código de cualquiera de los métodos, vaya a Azure Portal, vaya al contenedor de blobs para comprobar que existe un nuevo blob llamado sample-blob-{random}.txt con el mismo contenido que el archivo sample-source.txt:

Página de Azure Portal para el contenedor de blobs, que muestra el archivo cargado

Si creó una variable de entorno denominada AZURE_STORAGE_CONNECTION_STRING, también Blob Storage puede usar la CLI de Azure para comprobar que el blob existe mediante el comando az storage blob list:

az storage blob list --container-name blob-container-01

Si ha seguido las instrucciones para usar la autenticación sin contraseña, puede agregar el parámetro --connection-string al comando anterior con la cadena de conexión de la cuenta de almacenamiento. Para obtener la cadena de conexión, use el comando az storage account show-connection-string.

az storage account show-connection-string --resource-group PythonAzureExample-Storage-rg --name pythonazurestorage12345 --output tsv

Use la cadena de conexión completa como valor para el parámetro --connection-string.

Nota:

Si su cuenta de usuario Azure tiene el rol "Storage Blob Data Contributor" en el contenedor, puede usar el siguiente comando para listar los blobs en el contenedor:

az storage blob list --container-name blob-container-01 --account-name pythonazurestorage12345 --auth-mode login

6. Limpieza de recursos

Ejecute el comando az group delete si no necesita conservar el grupo de recursos y los recursos de almacenamiento usados en este ejemplo. Los grupos de recursos no incurren en cargos continuos en la suscripción, pero los recursos, como las cuentas de almacenamiento en el grupo de recursos pueden seguir incurriendo en cargos. Es recomendable limpiar cualquier grupo que no esté usando activamente. El argumento --no-wait permite que el comando devuelva el control inmediatamente en lugar de esperar a que finalice la operación.

az group delete -n PythonAzureExample-Storage-rg  --no-wait

También puede usar el método ResourceManagementClient.resource_groups.begin_delete para eliminar un grupo de recursos del código. El código de Ejemplo: Creación de un grupo de recursos muestra el uso.

Si ha seguido las instrucciones para usar la autenticación sin contraseña, es recomendable eliminar la entidad de servicio de la aplicación que creó. Puede usar el comando az ad app delete. Reemplace el marcador de posición <AZURE_CLIENT_ID> por el identificador de aplicación de la entidad de servicio.

az ad app delete --id <AZURE_CLIENT_ID>

Consulte también