相关文章推荐
失眠的啤酒  ·  Android | ...·  1 年前    · 

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

在本教程中,将创建用户分配的托管标识并将其分配给App 服务,以便它可以访问数据库和存储帐户资源。 有关使用系统托管标识的示例,请参阅 使用托管标识创建 Flask Python Web 应用并将其部署到 Azure 。 建议使用用户分配的标识,因为它们可由多个资源使用,并且其生命周期与它们关联的资源生命周期分离。 有关使用托管标识的最佳做法的详细信息,请参阅 托管标识最佳做法建议

本教程介绍如何使用 Azure CLI 部署 Python Web 应用和创建 Azure 资源。 可以在安装了 CLI 的任何环境中运行教程命令,例如本地环境、 Azure Cloud Shell GitHub Codespaces

获取示例应用

使用示例 Django 示例应用程序与本教程一起操作。 将示例应用程序下载或克隆到开发环境。

  • 克隆示例。

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

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

    创建 Azure PostgreSQL 灵活服务器

  • 设置本教程所需的环境变量,并使用 az group create 命令创建资源组。

    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"
    az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
    

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

  • 使用 az postgres flexible-server create 命令创建 PostgreSQL 灵活服务器 。 (此命令和后续命令对 Bash Shell ('\') 使用行继续符。 更改其他 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
    

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

  • 使用 az postgres flexible-server ad-admin create 命令将 Azure 帐户添加为服务器的 Azure AD 管理员。

    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
    
  • 使用 az postgres flexible-server firewall-rule create 命令在服务器上配置防火墙规则。 此规则允许本地环境访问以连接到服务器。 (如果使用 Azure Cloud Shell,可以跳过此步骤。)

    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
    

    使用任何显示 IP 地址的工具或网站在 命令中替换 <your IP> 。 例如,可以使用 什么是我的 IP 地址? 网站。

  • 使用 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 服务并将代码部署到其中。

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

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

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

  • 使用 az webapp config set 命令配置 App 服务 以使用示例存储库中的 start.sh

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

    创建存储帐户和容器

    示例应用将 中的图像作为 Blob 存储在 Azure 存储中。 存储帐户配置为允许公共访问容器。 应用使用托管标识和 DefaultAzureCredential 来访问存储帐户。

  • 使用 az storage create 命令创建存储帐户。

    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
    
  • 使用 az storage container create 命令在存储帐户中创建名为 photos 的容器。

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

    创建用户分配的托管标识

    创建用户分配的托管标识并将其分配给App 服务。 托管标识用于访问数据库和存储帐户。

  • 使用 az identity create 命令创建名为“UAManagedIdentityPythonTest”的用户分配的托管标识,并将客户端 ID 输出到变量供以后使用。

    UAClientID=$(az identity create --name UAManagedIdentityPythonTest --resource-group $RESOURCE_GROUP_NAME --query clientId --output tsv)
    echo $UAClientID
    
  • 使用 az account show 命令获取订阅 ID,并将其输出到可用于构造托管标识的资源 ID 的变量。

    SUBSCRIPTION_ID=$(az account show --query id --output tsv)
    RESOURCE_ID="/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.ManagedIdentity/userAssignedIdentities/UAManagedIdentityPythonTest"
    echo $RESOURCE_ID
    
  • 使用 az webapp identity assign 命令将托管标识分配给App 服务。

    export MSYS_NO_PATHCONV=1
    az webapp identity assign \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $APP_SERVICE_NAME \
        --identities $RESOURCE_ID
    
  • 使用 az webapp config appsettings set 命令创建包含托管标识的客户端 ID 和其他配置信息的App 服务应用设置。

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

    示例应用使用环境变量 (应用设置) 定义数据库和存储帐户的连接信息,但不包括密码。 相反,身份验证是使用 无密码完成的 DefaultAzureCredential

    所示的存储库代码使用 DefaultAzureCredential 类构造函数,而无需将用户分配的托管标识客户端 ID 传递给构造函数。 在此方案中,回退是针对AZURE_CLIENT_ID环境变量(设置为应用设置)检查。

    如果AZURE_CLIENT_ID环境变量不存在,则将使用系统分配的托管标识(如果已配置)。 如果未配置系统分配的托管标识,代码将回退到使用服务主体。 有关详细信息,请参阅 DefaultAzureCredential 简介

    为托管标识创建角色

    在本部分中,为托管标识创建角色分配,以启用对存储帐户和数据库的访问。

  • 为托管标识创建角色分配,以使用 az role assignment create 命令启用对存储帐户的访问。

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

    命令指定资源组的角色分配范围。 有关详细信息,请参阅 了解角色分配

  • 使用 az postgres flexible-server execute 命令连接到 Postgres 数据库,并运行相同的命令,将角色分配给托管标识。

    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('UAManagedIdentityPythonTest', false, false);select * from pgaadauth_list_principals(false);"
    

    如果在运行命令时遇到问题,请确保将用户帐户添加为 PosgreSQL 服务器的 Azure AD 管理员,并且已允许访问防火墙规则中的 IP 地址。 有关详细信息,请参阅 创建 Azure PostgreSQL 灵活服务器部分。

    在 Azure 中测试 Python Web 应用

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

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

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

  • 通过添加餐厅以及包含餐厅照片的一些评论来测试示例应用的功能。

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

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

    az group delete  --name $RESOURCE_GROUP_NAME 
    

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

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

  • 在 Azure 应用服务 中使用 PostgreSQL 部署 Python (Django 或 Flask) Web 应用

  •