使用系统分配的托管标识创建 Flask Python Web 应用并将其部署到 Azure

在本教程中,你将部署 Python Flask 代码来创建和部署在 Azure App 服务 中运行的 Web 应用。 Web 应用使用其系统分配的托管标识(无密码连接)和 Azure 基于角色的访问控制来访问Azure 存储Azure Database for PostgreSQL 灵活服务器资源。 该代码使用用于 Python 的 Azure 标识客户端库的 DefaultAzureCredential 类。 该DefaultAzureCredential类会自动检测App 服务是否存在托管标识,并使用它访问其他 Azure 资源。

可以使用服务连接或手动配置与 Azure 服务的无密码连接。 本教程演示如何使用服务连接or。 有关无密码连接的详细信息,请参阅 Azure 服务的无密码连接。 有关服务连接or 的信息,请参阅服务连接or 文档

本教程介绍如何使用 Azure CLI 创建和部署 Python Web 应用。 本教程中的命令编写为在 Bash shell 中运行。 可以在安装 CLI 的任何 Bash 环境中运行教程命令,例如本地环境或 Azure Cloud Shell。 通过一些修改(例如设置和使用环境变量),可以在 Windows 命令行界面等其他环境中运行这些命令。 有关使用用户分配的托管标识的示例,请参阅 使用用户分配的托管标识创建 Django Web 应用并将其部署到 Azure。

获取示例应用

使用 Flask 框架的示例 Python 应用程序可帮助你遵循本教程。 请将一个示例应用程序下载或克隆到本地工作站。

  1. 在 Azure Cloud Shell 会话中克隆示例。

    git clone https://github.com/Azure-Samples/msdocs-flask-web-app-managed-identity.git
    
  2. 导航到应用程序文件夹。

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

创建 Azure PostgreSQL 服务器

  1. 设置本教程所需的环境变量。

    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"
    

    重要

    必须 ADMIN_PW 包含以下三个类别中的 8 到 128 个字符:英语大写字母、英文小写字母、数字和非字母数字。 创建用户名或密码时不要使用 $ 字符。 稍后,将使用这些值创建环境变量,其中 $ 字符在用于运行 Python 应用的 Linux 容器中具有特殊含义。

  2. 使用“az group create”命令创建资源组。

    az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
    
  3. 使用 az postgres flexible-server create 命令创建 PostgreSQL 服务器。 (此命令和后续命令对 Bash Shell 使用行延续字符('\')。 根据需要更改 shell 的行继续符。

    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
    

    SKU 名称是定价层和计算配置的名称。 有关详细信息,请参阅 Azure Database for PostgreSQL 定价。 若要列出可用的 SKU,请使用 az postgres flexible-server list-skus --location $LOCATION

  4. 使用 az postgres flexible-server execute 命令创建名为restaurant的数据库。

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

创建Azure App 服务并部署代码

  1. 使用 az webapp up 命令创建应用服务。

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

    SKU 定义应用服务计划的大小(CPU、内存)和成本。 B1(基本)服务计划在 Azure 订阅中会产生少量成本。 有关应用服务计划的完整列表,请查看应用服务定价页。

  2. 将App 服务配置为将存储库中的 start.sh 与 az webapp config set 命令一起使用

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

创建到 Azure 资源的无密码连接器

服务连接or 命令将Azure 存储和 Azure Database for PostgreSQL 资源配置为使用托管标识和 Azure 基于角色的访问控制。 这些命令在将 Web 应用连接到这些资源的App 服务中创建应用设置。 命令的输出列出了为启用无密码功能而采取的服务连接器操作。

  1. 使用 az webapp connection create postgres-flexible 命令添加 PostgreSQL 服务连接器。 系统分配的托管标识用于向目标资源 PostgreSQL 对 Web 应用进行身份验证。

    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. 使用 az webapp connection create storage-blob 命令添加存储服务连接器。

    此命令还会添加存储帐户,并将角色存储 Blob 数据参与者的 Web 应用添加到存储帐户。

    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))
    

在存储帐户中创建容器

示例 Python 应用将审阅者提交的照片存储为存储帐户中容器中的 blob。

  • 当用户通过审阅提交照片时,示例应用使用系统分配的托管标识将映像写入容器,以便进行身份验证和授权。 在最后一节中配置了此功能。

  • 当用户查看餐馆的评论时,该应用将返回 Blob 存储中照片的链接,该照片的每个评论都有一个与之关联的评论。 要使浏览器能够显示照片,它必须能够在存储帐户中访问它。 Blob 数据必须可用于通过匿名(未经身份验证)访问公开读取。

为了增强安全性,存储帐户是使用默认禁用的对 blob 数据的匿名访问创建的。 在本部分中,将在存储帐户上启用匿名读取访问权限,然后创建一个名为 照片 的容器,该容器提供对其 Blob 的公共(匿名)访问。

  1. 使用 az storage account update 命令更新存储帐户以允许匿名读取对 blob 的访问。

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

    在存储帐户上启用匿名访问不会影响单个 Blob 的访问。 必须在容器级别显式启用对 Blob 的公共访问。

  2. 使用 az storage container create 命令在存储帐户中创建名为照片容器。 允许匿名读取(公共)访问新创建的容器中的 Blob。

    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) 
    

    注意

    为简洁起见,此命令使用存储帐户密钥对存储帐户进行授权。 对于大多数方案,Microsoft 建议的方法是使用 Microsoft Entra ID 和 Azure (RBAC) 角色。 有关一组快速说明,请参阅 快速入门:使用 Azure CLI 创建、下载和列出 Blob。 请注意,多个 Azure 角色允许在存储帐户中创建容器,包括“所有者”、“参与者”、“存储 Blob 数据所有者”和“存储 Blob 数据参与者”。

若要详细了解对 Blob 数据的匿名读取访问,请参阅 为容器和 Blob 配置匿名读取访问权限。

在 Azure 中测试 Python Web 应用

示例 Python 应用使用 azure.identity 包及其 DefaultAzureCredential 类。 当应用在 Azure 中运行时,DefaultAzureCredential自动检测App 服务是否存在托管标识,如果是,则使用它访问其他 Azure 资源(在本例中为存储和 PostgreSQL)。 无需向App 服务提供存储密钥、证书或凭据即可访问这些资源。

  1. 在 URL http://$APP_SERVICE_NAME.azurewebsites.net中浏览到已部署的应用程序。

    应用可能需要一两分钟才能启动。 如果看到不是默认示例应用页面的默认应用页面,请等待一分钟并刷新浏览器。

  2. 通过添加餐厅以及一些带有餐厅照片的评论来测试示例应用的功能。

    餐厅和评论信息存储在 Azure Database for PostgreSQL 中,照片存储在Azure 存储中。 下面是示例屏幕截图:

    示例应用的屏幕截图,其中显示了使用 Azure App 服务、Azure Postgre SQL 数据库 和 Azure 存储 的餐馆评审功能。

清理

在本教程中,所有 Azure 资源都在同一资源组中创建。 使用 az group delete 命令删除资源组会删除资源组中的所有资源,并且是删除用于应用的所有 Azure 资源的最快捷方法。

az group delete  --name $RESOURCE_GROUP_NAME 

可以选择性地添加 --no-wait 参数,以允许命令在操作完成之前返回。

后续步骤