使用系統指派的受控識別,建立 Flask Python Web 應用程式並將其部署至 Azure
在本教學課程中,您會部署 Python Flask 程式代碼,以建立及部署在 Azure App 服務 中執行的 Web 應用程式。 Web 應用程式會使用其系統指派的受控識別(無密碼連線)搭配 Azure 角色型訪問控制來存取 Azure 儲存體 和 適用於 PostgreSQL 的 Azure 資料庫 - 彈性伺服器資源。 此程式代碼會使用適用於 Python 的 Azure 身分識別用戶端連結庫的 DefaultAzureCredential 類別。 類別 DefaultAzureCredential
會自動偵測 App Service 的受控識別是否存在,並用它來存取其他 Azure 資源。
您可以使用 Service Connector 設定 Azure 服務的無密碼連線,也可以手動設定它們。 本教學課程示範如何使用 Service Connector。 如需無密碼連線的詳細資訊,請參閱 Azure 服務的無密碼連線。 如需 Service Connector 的相關信息,請參閱 Service Connector 檔。
本教學課程說明如何使用 Azure CLI 建立及部署 Python Web 應用程式。 本教學課程中的命令會撰寫成在Bash殼層中執行。 您可以在任何已安裝 CLI 的 Bash 環境中執行教學課程命令,例如本機環境或 Azure Cloud Shell。 透過一些修改 -- 例如,設定和使用環境變數 -- 您可以在 Windows 命令殼層等其他環境中執行這些命令。 如需使用使用者指派受控識別的範例,請參閱 使用使用者指派的受控識別,建立 Django Web 應用程式並將其部署至 Azure。
取得範例應用程式
您可以使用 Flask 架構的範例 Python 應用程式,協助您遵循本教學課程。 下載或複製其中一個範例應用程式至本機工作站。
在 Azure Cloud Shell 工作階段中複製範例。
git clone https://github.com/Azure-Samples/msdocs-flask-web-app-managed-identity.git
瀏覽至應用程式資料夾。
cd msdocs-flask-web-app-managed-identity
檢查驗證碼
範例 Web 應用程式必須向兩個不同的資料存放區進行驗證:
- Azure Blob 記憶體伺服器會儲存並擷取檢閱者提交的相片。
- 適用於 PostgreSQL 的 Azure 資料庫 - 彈性伺服器資料庫,其儲存餐廳與評論。
它會使用 DefaultAzureCredential 向這兩個數據存放區進行驗證。 使用 DefaultAzureCredential
時,應用程式可以設定為在不同的服務主體身分識別下執行,視其執行環境而定,而不需變更程序代碼。 例如,在本機開發環境中,應用程式可以在開發人員登入 Azure CLI 的身分識別下執行,而在 Azure 中,如本教學課程所示,它可以在其系統指派的受控識別下執行。
不論是哪一種情況,應用程式執行的安全性主體都必須在應用程式所使用的每個 Azure 資源上具有角色,才能在應用程式所需的資源上執行動作。 在本教學課程中,您會使用服務連接器,在 Azure 中的應用程式中自動啟用系統指派的受控識別,並在 Azure 記憶體帳戶和 適用於 PostgreSQL 的 Azure 資料庫 伺服器上指派該身分識別適當的角色。
啟用系統指派的受控識別,並在數據存放區上指派適當的角色之後,您可以使用 DefaultAzureCredential
來向所需的 Azure 資源進行驗證。
下列程式代碼可用來建立 Blob 記憶體用戶端,以在中 app.py
上傳相片。 的實例 DefaultAzureCredential
會提供給用戶端,用來取得存取令牌,以對 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)
的DefaultAzureCredential
實例也可用來取得 中 ./azureproject/get_conn.py
適用於 PostgreSQL 的 Azure 資料庫的存取令牌。 在此情況下,令牌會直接透過在認證實例上呼叫 get_token ,並傳遞適當的 scope
值來取得令牌。 然後,令牌會用來取代傳回給呼叫端的 PostgreSQL 連線 URI 中的密碼。
azure_credential = DefaultAzureCredential()
token = azure_credential.get_token("https://ossrdbms-aad.database.windows.net")
conn = str(current_app.config.get('DATABASE_URI')).replace('PASSWORDORTOKEN', token.token)
若要深入瞭解如何使用 Azure 服務驗證您的應用程式,請參閱 使用適用於 Python 的 Azure SDK 向 Azure 服務驗證 Python 應用程式。 若要深入瞭解 DefaultAzureCredential
,包括如何針對您的環境自定義認證鏈結,請參閱 DefaultAzureCredential 概觀。
建立 Azure PostgreSQL 伺服器
設定教學課程所需的環境變數。
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 容器中具有特殊意義。使用 az group create 命令來建立資源群組。
az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
使用 az postgres flexible-server create 命令建立 PostgreSQL 伺服器。 (這個和後續的命令會使用BashShell('\' 的行接續字元)。 視需要變更殼層的行接續字元。
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-name 是定價層和計算組態的名稱。 如需詳細資訊,請參閱適用於 PostgreSQL 的 Azure 資料庫定價。 若要列出可用的 SKU, 請使用
az postgres flexible-server list-skus --location $LOCATION
。使用 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 命令建立 App Service。
az webapp up \ --resource-group $RESOURCE_GROUP_NAME \ --name $APP_SERVICE_NAME \ --runtime PYTHON:3.9 \ --sku B1
SKU 會定義 App Service 方案的大小(CPU、記憶體)和成本。 B1 (基本) 服務方案會在您的 Azure 訂用帳戶中產生少量成本。 如需 App Service 方案的完整清單,請檢視 App Service 定價頁面。
將 App Service 設定為使用 存放庫中的 start.sh 與 az webapp config set 命令。
az webapp config set \ --resource-group $RESOURCE_GROUP_NAME \ --name $APP_SERVICE_NAME \ --startup-file "start.sh"
建立 Azure 資源的無密碼連接器
Service Connector 命令會將 Azure 儲存體 和 適用於 PostgreSQL 的 Azure 資料庫 資源設定為使用受控識別和 Azure 角色型存取控制。 命令會在 App Service 中建立應用程式設定,以將 Web 應用程式連線到這些資源。 命令的輸出會列出用來啟用無密碼功能的服務連接器動作。
使用 az webapp connection create postgres-flexible 命令新增 PostgreSQL 服務連接器。 系統指派的受控識別可用來向目標資源驗證 Web 應用程式,在此案例中為 PostgreSQL。
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
使用 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 數據來建立。 在本節中,您會在記憶體帳戶上啟用匿名讀取許可權,然後建立名為 photos 的容器,以提供其 Blob 的公用(匿名)存取權。
使用 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 的公用存取權。
使用 az storage container create 命令,在記憶體帳戶中建立名為 photos 的容器。 允許對新建立容器中的 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 Service 是否有受控識別存在,如果是的話,則會使用它來存取其他 Azure 資源(在此案例中為記憶體和 PostgreSQL)。 不需要提供記憶體金鑰、憑證或認證給 App Service,才能存取這些資源。
流覽至 URL
http://$APP_SERVICE_NAME.azurewebsites.net
的已部署應用程式。應用程式可能需要一兩分鐘的時間才能啟動。 如果您看到預設的應用程式頁面不是預設範例應用程式頁面,請稍候一分鐘並重新整理瀏覽器。
藉由新增餐廳以及一些具有餐廳相片的評論,測試範例應用程式的功能。
餐廳和評論資訊儲存在 適用於 PostgreSQL 的 Azure 資料庫,照片儲存在 Azure 儲存體。 以下是範例螢幕快照:
清理
在本教學課程中,所有 Azure 資源都是在相同的資源群組中建立的。 使用 az group delete 命令移除資源群組會移除資源群組中的所有資源,這是移除應用程式所用所有 Azure 資源最快的方式。
az group delete --name $RESOURCE_GROUP_NAME
您可以選擇性地新增 --no-wait
自變數,以允許命令在作業完成之前傳回。