시스템 할당 관리 ID를 사용하여 Flask Python 웹앱을 만들고 Azure에 배포
이 자습서에서는 Python Flask 코드를 배포하여 Azure 앱 Service에서 실행되는 웹앱을 만들고 배포합니다. 웹앱은 Azure 역할 기반 액세스 제어와 함께 시스템 할당 관리 ID(암호 없는 연결)를 사용하여 Azure Storage 및 Azure Database for PostgreSQL - 유연한 서버 리소스에 액세스합니다. 이 코드는 Python용 Azure Identity 클라이언트 라이브러리의 DefaultAzureCredential 클래스를 사용합니다. 클래스는 DefaultAzureCredential
App Service에 대한 관리 ID가 있는지 자동으로 검색하고 이를 사용하여 다른 Azure 리소스에 액세스합니다.
Service Connector를 사용하여 Azure 서비스에 대한 암호 없는 연결을 구성하거나 수동으로 구성할 수 있습니다. 이 자습서에서는 서비스 커넥터를 사용하는 방법을 보여줍니다. 암호 없는 연결에 대한 자세한 내용은 Azure 서비스에 대한 암호 없는 연결을 참조 하세요. 서비스 커넥터에 대한 자세한 내용은 Service Connector 설명서를 참조 하세요.
이 자습서에서는 Azure CLI를 사용하여 Python 웹앱을 만들고 배포하는 방법을 보여줍니다. 이 자습서의 명령은 Bash 셸에서 실행되도록 작성되었습니다. 로컬 환경 또는 Azure Cloud Shell과 같이 CLI가 설치된 모든 Bash 환경에서 자습서 명령을 실행할 수 있습니다. 환경 변수 설정 및 사용과 같은 일부 수정을 통해 Windows 명령 셸과 같은 다른 환경에서 이러한 명령을 실행할 수 있습니다. 사용자 할당 관리 ID를 사용하는 예제는 사용자 할당 관리 ID를 사용하여 Django 웹앱 만들기 및 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
인증 코드 검사
샘플 웹앱은 두 개의 서로 다른 데이터 저장소에 인증해야 합니다.
- 검토자가 제출한 사진을 저장하고 검색하는 Azure Blob Storage 서버입니다.
- Azure Database for PostgreSQL - 레스토랑과 리뷰를 저장하는 유연한 서버 데이터베이스입니다.
DefaultAzureCredential을 사용하여 두 데이터 저장소에 인증합니다. DefaultAzureCredential
앱을 사용하면 코드를 변경하지 않고 실행 중인 환경에 따라 다른 서비스 주체의 ID로 실행되도록 앱을 구성할 수 있습니다. 예를 들어 로컬 개발 환경에서 앱은 Azure CLI에 로그인한 개발자의 ID로 실행되고, Azure에서는 이 자습서와 같이 시스템 할당 관리 ID로 실행할 수 있습니다.
두 경우 모두 앱이 실행되는 보안 주체에는 앱이 사용하는 각 Azure 리소스에 대한 역할이 있어야 하며, 이를 통해 앱에 필요한 리소스에 대한 작업을 수행할 수 있습니다. 이 자습서에서는 서비스 커넥터를 사용하여 Azure에서 앱에서 시스템 할당 관리 ID를 자동으로 사용하도록 설정하고 Azure Storage 계정 및 Azure Database for PostgreSQL 서버에서 해당 ID에 적절한 역할을 할당합니다.
시스템 할당 관리 ID를 사용하도록 설정하고 데이터 저장소에 적절한 역할을 할당한 후에는 필요한 Azure 리소스로 인증하는 데 사용할 DefaultAzureCredential
수 있습니다.
다음 코드는 사진을 app.py
업로드할 Blob Storage 클라이언트를 만드는 데 사용됩니다. 인스턴스 DefaultAzureCredential
는 Azure Storage에 대한 작업을 수행하기 위해 액세스 토큰을 획득하는 데 사용하는 클라이언트에 제공됩니다.
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
는 Azure Database for PostgreSQL ./azureproject/get_conn.py
에 대한 액세스 토큰을 가져오는 데도 사용됩니다. 이 경우 토큰은 자격 증명 인스턴스에서 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"
Important
ADMIN_PW
영어 대문자, 영어 소문자, 숫자 및 무수 문자의 세 가지 범주에서 8~128자를 포함해야 합니다. 사용자 이름 또는 암호를 만들 때$
문자를 사용하지 않습니다. 나중에 Python 앱을 실행하는 데 사용되는 Linux 컨테이너 내에서 문자에 특별한 의미가 있는$
이러한 값을 사용하여 환경 변수를 만듭니다.az group create 명령을 사용하여 리소스 그룹을 만듭니다.
az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
az postgres flexible-server create 명령을 사용하여 PostgreSQL 서버를 만듭니 다. (이 명령과 후속 명령은 Bash 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-name은 가격 책정 계층 및 컴퓨팅 구성의 이름입니다. 자세한 내용은 Azure Database for PostgreSQL 가격 책정을 참조하세요. 사용 가능한 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 앱 서비스 만들기 및 코드 배포
az webapp up 명령을 사용하여 앱 서비스를 만듭니다 .
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 가격 책정 페이지를 참조하세요.
az webapp config set 명령을 사용하여 리포지토리의 start.sh 사용하도록 App Service를 구성합니다.
az webapp config set \ --resource-group $RESOURCE_GROUP_NAME \ --name $APP_SERVICE_NAME \ --startup-file "start.sh"
Azure 리소스에 대한 암호 없는 커넥터 만들기
서비스 커넥터 명령은 관리 ID 및 Azure 역할 기반 액세스 제어를 사용하도록 Azure Storage 및 Azure Database for PostgreSQL 리소스를 구성합니다. 명령은 App Service에서 웹앱을 이러한 리소스에 연결하는 앱 설정을 만듭니다. 명령의 출력에는 암호 없는 기능을 사용하도록 설정하기 위해 수행된 서비스 커넥터 작업이 나열됩니다.
az webapp connection create postgres-flexible 명령을 사용하여 PostgreSQL 서비스 커넥터를 추가합니다. 시스템 할당 관리 ID는 대상 리소스인 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 명령을 사용하여 스토리지 서비스 커넥터를 추가합니다.
또한 이 명령은 스토리지 계정을 추가하고 Storage Blob 데이터 기여자 역할이 있는 웹앱을 스토리지 계정에 추가합니다.
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으로 저장합니다.
사용자가 검토를 통해 사진을 제출하면 샘플 앱은 인증 및 권한 부여를 위해 시스템 할당 관리 ID를 사용하여 이미지를 컨테이너에 씁니다. 마지막 섹션에서 이 기능을 구성했습니다.
사용자가 식당에 대한 리뷰를 볼 때 앱은 연결된 리뷰마다 Blob Storage의 사진에 대한 링크를 반환합니다. 브라우저에서 사진을 표시하려면 스토리지 계정에서 사진에 액세스할 수 있어야 합니다. Blob 데이터는 익명(인증되지 않은) 액세스를 통해 공개적으로 읽을 수 있어야 합니다.
보안을 강화하기 위해 기본적으로 사용하지 않도록 설정된 Blob 데이터에 대한 익명 액세스를 사용하여 스토리지 계정을 만듭니다. 이 섹션에서는 스토리지 계정에서 익명 읽기 액세스를 사용하도록 설정한 다음 해당 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 데이터 소유자" 및 "Storage Blob 데이터 기여자"를 포함하여 스토리지 계정에 컨테이너를 만들 수 있습니다.
Blob 데이터에 대한 익명 읽기 액세스에 대한 자세한 내용은 컨테이너 및 Blob에 대한 익명 읽기 액세스 구성을 참조하세요.
Azure에서 Python 웹앱 테스트
샘플 Python 앱은 azure.identity 패키지 및 해당 클래스를 DefaultAzureCredential
사용합니다. 앱이 Azure DefaultAzureCredential
에서 실행 중인 경우 App Service에 대한 관리 ID가 있는지 자동으로 감지하고, 이 경우 이를 사용하여 다른 Azure 리소스(이 경우 스토리지 및 PostgreSQL)에 액세스합니다. 이러한 리소스에 액세스하기 위해 App Service에 스토리지 키, 인증서 또는 자격 증명을 제공할 필요가 없습니다.
URL
http://$APP_SERVICE_NAME.azurewebsites.net
에서 배포된 애플리케이션을 찾습니다.앱을 시작하는 데 1~2분 정도 걸릴 수 있습니다. 기본 샘플 앱 페이지가 아닌 기본 앱 페이지가 표시되면 잠시 기다렸다가 브라우저를 새로 고칩니다.
레스토랑에 대한 사진과 함께 일부 리뷰를 추가하여 샘플 앱의 기능을 테스트합니다.
레스토랑 및 검토 정보는 Azure Database for PostgreSQL에 저장되고 사진은 Azure Storage에 저장됩니다. 다음은 예제 스크린샷입니다.
정리
이 자습서에서는 모든 Azure 리소스가 동일한 리소스 그룹에 만들어졌습니다. az group delete 명령을 사용하여 리소스 그룹을 제거하면 리소스 그룹의 모든 리소스가 제거되며 앱에 사용되는 모든 Azure 리소스를 제거하는 가장 빠른 방법입니다.
az group delete --name $RESOURCE_GROUP_NAME
필요에 따라 --no-wait
인수를 추가하여 작업이 완료되기 전에 명령이 반환되도록 할 수 있습니다.