在本教程中,将
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 应用