예: Python용 Azure 라이브러리를 사용하여 Azure Storage에 액세스

이 문서에서는 Python 애플리케이션 코드의 Azure 클라이언트 라이브러리를 사용하여 Azure Blob Storage 컨테이너에 파일을 업로드하는 방법을 알아봅니다. 이 문서에서는 예제: Azure Storage 만들기에 표시된 리소스를 만들었다고 가정합니다.

이 문서의 모든 명령은 언급되지 않는 한 Linux/macOS bash 및 Windows 명령 셸에서 동일하게 작동합니다.

1. 로컬 개발 환경 설정

아직 실행하지 않은 경우 이 코드를 실행할 수 있는 환경을 설정합니다. 다음은 몇 가지 옵션입니다.

  • 사용하거나 선택한 도구를 사용하여 venv Python 가상 환경을 구성합니다. 로컬 또는 Azure Cloud Shell에서 가상 환경을 만들고 해당 환경에서 코드를 실행할 수 있습니다. 가상 환경을 활성화하여 사용을 시작해야 합니다.

  • conda 환경을 사용합니다.

  • Visual Studio Code 또는 GitHub Codespaces에서 개발 컨테이너를 사용합니다.

2. 라이브러리 패키지 설치

requirements.txt 파일에서 필요한 클라이언트 라이브러리 패키지에 대한 줄을 추가하고 파일을 저장합니다.

azure-storage-blob
azure-identity

그런 다음 터미널 또는 명령 프롬프트에서 요구 사항을 설치합니다.

pip install -r requirements.txt

3. 업로드할 파일 만들기

sample-source.txt 소스 파일을 만듭니다. 이 파일 이름은 코드에서 예상하는 이름입니다.

Hello there, Azure Storage. I'm a friendly file ready to be stored in a blob.

4. 앱 코드에서 Blob Storage 사용

이 섹션에서는 예제에서 만든 Blob 컨테이너의 데이터에 액세스하는 두 가지 방법인 Azure Storage를 만드는 방법을 보여 줍니다. Blob 컨테이너의 데이터에 액세스하려면 앱이 Azure로 인증하고 컨테이너의 데이터에 액세스할 수 있는 권한을 부여받아야 합니다. 이 섹션에서는 다음 두 가지 방법을 제공합니다.

  • 암호 없는(권장) 메서드는 을 사용하여 DefaultAzureCredential앱을 인증합니다. DefaultAzureCredential 는 개발자 도구 자격 증명, 애플리케이션 서비스 주체 및 관리 ID를 포함하여 다양한 자격 증명 시퀀스를 사용하여 앱(또는 사용자)을 인증할 수 있는 연결된 자격 증명입니다.

  • Connection 문자열 메서드는 연결 문자열 사용하여 스토리지 계정에 직접 액세스합니다.

다음과 같은 이유로 가능하면 암호 없는 메서드를 사용하는 것이 좋습니다.

  • 연결 문자열 해당 계정 내의 개별 리소스가 아닌 Storage 계정으로 연결 에이전트를 인증합니다. 결과적으로 연결 문자열 필요한 것보다 더 광범위한 권한 부여를 부여합니다. Azure DefaultAzureCredential RBAC를 사용하여 앱이 실행되는 ID에 스토리지 리소스에 대해 더 세분화되고 최소 권한 있는 권한을 부여할 수 있습니다.

  • 연결 문자열 일반 텍스트로 액세스 정보를 포함하므로 제대로 생성되거나 보호되지 않으면 잠재적인 취약성이 발생합니다. 이러한 연결 문자열 노출되면 Storage 계정 내에서 광범위한 리소스에 액세스하는 데 사용할 수 있습니다.

  • 연결 문자열 일반적으로 환경 변수에 저장되므로 공격자가 사용자 환경에 액세스하는 경우 손상에 취약해집니다. 지원되는 DefaultAzureCredential 대부분의 자격 증명 형식은 사용자 환경에 비밀을 저장할 필요가 없습니다.

DefaultAzureCredential 는 미리 구성된 의견 있는 자격 증명 체인입니다. 가장 일반적인 인증 흐름 및 개발자 도구와 함께 많은 환경을 지원하도록 설계되었습니다. 인스턴스는 런타임 환경의 DefaultAzureCredential 조합, 잘 알려진 특정 환경 변수의 값 및 필요에 따라 해당 생성자에 전달된 매개 변수를 기반으로 토큰을 가져오려고 하는 자격 증명 형식을 결정합니다.

다음 단계에서는 애플리케이션 서비스 주체를 애플리케이션 ID로 구성합니다. 애플리케이션 서비스 주체는 로컬 개발 중과 온-프레미스에서 호스트되는 앱 모두에 적합합니다. 애플리케이션 서비스 주체를 사용하도록 구성 DefaultAzureCredential 하려면 다음 환경 변수를 설정합니다. AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_CLIENT_SECRET

클라이언트 암호가 구성되어 있는지 확인합니다. 이는 애플리케이션 서비스 주체에 필요하지만 시나리오에 따라 환경 변수에서 비밀 또는 암호를 설정할 필요가 없는 자격 증명을 사용하도록 구성할 DefaultAzureCredential 수도 있습니다.

예를 들어 로컬 개발에서 구성된 환경 변수를 사용하여 토큰을 가져올 수 없는 경우 Azure CLI와 같은 개발 도구에 로그인한 사용자(이미)를 사용하여 토큰을 가져오려고 합니다. Azure DefaultAzureCredential 에서 호스트되는 앱의 경우 DefaultAzureCredential 관리 ID를 사용하도록 구성할 수 있습니다. 모든 경우에 앱의 코드는 동일하게 유지되며 구성 및/또는 런타임 환경만 변경됩니다.

  1. 다음 코드를 사용하여 use_blob_auth.py라는 파일을 만듭니다. 주석은 단계를 설명합니다.

    import os
    import uuid
    
    from azure.identity import DefaultAzureCredential
    
    # Import the client object from the SDK library
    from azure.storage.blob import BlobClient
    
    credential = DefaultAzureCredential()
    
    # Retrieve the storage blob service URL, which is of the form
    # https://<your-storage-account-name>.blob.core.windows.net/
    storage_url = os.environ["AZURE_STORAGE_BLOB_URL"]
    
    # Create the client object using the storage URL and the credential
    blob_client = BlobClient(
        storage_url,
        container_name="blob-container-01",
        blob_name=f"sample-blob-{str(uuid.uuid4())[0:5]}.txt",
        credential=credential,
    )
    
    # Open a local file and upload its contents to Blob Storage
    with open("./sample-source.txt", "rb") as data:
        blob_client.upload_blob(data)
        print(f"Uploaded sample-source.txt to {blob_client.url}")
    

    참조 링크:

  2. 다음과 같은 환경 변수를 만듭니다 AZURE_STORAGE_BLOB_URL.

    set AZURE_STORAGE_BLOB_URL=https://pythonazurestorage12345.blob.core.windows.net
    

    "pythonazurestorage12345"를 스토리지 계정의 이름으로 바꿉니다.

    AZURE_STORAGE_BLOB_URL 환경 변수는 이 예제에서만 사용됩니다. Azure 라이브러리에서 사용되지 않습니다.

  3. az ad sp create-for-rbac 명령을 사용하여 앱에 대한 새 서비스 주체를 만듭니다. 이 명령은 앱에 대한 앱 등록을 동시에 만듭니다. 서비스 주체에 선택한 이름을 지정합니다.

    az ad sp create-for-rbac --name <service-principal-name>
    

    이 명령의 출력은 다음과 같습니다. 다음 단계에서 이러한 값이 필요하고 암호(클라이언트 암호) 값을 다시 볼 수 없으므로 이러한 값을 기록하거나 이 창을 열어 둡니다. 그러나 필요한 경우 서비스 주체 또는 기존 암호를 무효화하지 않고 나중에 새 암호를 추가할 수 있습니다.

    {
      "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
      "displayName": "<service-principal-name>",
      "password": "Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2",
      "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
    }
    

    Azure CLI 명령은 Azure Cloud Shell에서 실행하거나 Azure CLI가 설치된 워크스테이션에서 실행할 수 있습니다.

  4. 애플리케이션 서비스 주체에 대한 환경 변수를 만듭니다.

    이전 명령의 출력 값을 사용하여 다음 환경 변수를 만듭니다. 이러한 변수는 애플리케이션 서비스 주체를 사용하도록 지시 DefaultAzureCredential 합니다.

    • AZURE_CLIENT_ID → 앱 ID 값입니다.
    • AZURE_TENANT_ID → 테넌트 ID 값입니다.
    • AZURE_CLIENT_SECRET → 앱에 대해 생성된 암호/자격 증명입니다.
    set AZURE_CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
    set AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
    set AZURE_CLIENT_SECRET=Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2
    
  5. 의도적으로 실패하는 코드를 실행하려고 시도합니다.

    python use_blob_auth.py
    
  6. "이 요청은 이 권한을 사용하여 이 작업을 수행할 권한이 없습니다." 오류를 확인합니다. 사용 중인 로컬 서비스 주체에 Blob 컨테이너에 액세스할 수 있는 권한이 아직 없기 때문에 오류가 발생합니다.

  7. az role assignment create Azure CLI 명령을 사용하여 Blob 컨테이너에 대한 Storage Blob 데이터 기여자 권한을 서비스 주체에게 부여합니다.

    az role assignment create --assignee <AZURE_CLIENT_ID> \
        --role "Storage Blob Data Contributor" \
        --scope "/subscriptions/<AZURE_SUBSCRIPTION_ID>/resourceGroups/PythonAzureExample-Storage-rg/providers/Microsoft.Storage/storageAccounts/pythonazurestorage12345/blobServices/default/containers/blob-container-01"
    

    인수는 --assignee 서비스 주체를 식별합니다. AZURE_CLIENT_ID> 자리 표시자를 서비스 주체의 앱 ID로 바꿉<니다.

    인수는 --scope 이 역할 할당이 적용되는 위치를 식별합니다. 이 예제에서는 "Blob-container-01"이라는 컨테이너의 서비스 주체에 "Storage Blob 데이터 기여자" 역할을 부여합니다.

    • 스토리지 계정과 pythonazurestorage12345 스토리지 계정의 정확한 이름을 포함하는 리소스 그룹으로 바꿉 PythonAzureExample-Storage-rg 니다. 또한 필요한 경우 Blob 컨테이너의 이름을 조정합니다. 잘못된 이름을 사용하는 경우 "중첩된 리소스에 대해 요청된 작업을 수행할 수 없습니다. 부모 리소스 'pythonazurestorage12345'를 찾을 수 없습니다."

    • <AZURE_SUBSCRIPTION_ID> 자리 표시자를 Azure 구독 ID로 바꿉니다. (az account show 명령을 실행하고 출력의 속성에서 구독 ID를 id 가져올 수 있습니다.)

    bash 셸을 사용할 때 역할 할당 명령이 "연결 어댑터를 찾을 수 없음" 오류를 반환하는 경우 경로 변환을 방지하도록 설정 export MSYS_NO_PATHCONV=1 해 봅니다. 자세한 내용은 이 문제를 참조하세요.

  8. 사용 권한이 전파되기까지 1~2분 정도 기다린 다음 코드를 다시 실행하여 이제 작동하는지 확인합니다. 사용 권한 오류가 다시 표시되면 조금 더 기다린 다음 코드를 다시 시도하세요.

역할 할당에 대한 자세한 내용은 Azure CLI를 사용하여 역할 권한을 할당하는 방법을 참조하세요.

Important

이전 단계에서 앱은 애플리케이션 서비스 주체에서 실행되었습니다. 애플리케이션 서비스 주체를 구성하려면 클라이언트 암호가 필요합니다. 그러나 동일한 코드를 사용하여 환경에서 암호 또는 비밀을 명시적으로 구성할 필요가 없는 다양한 자격 증명 형식으로 앱을 실행할 수 있습니다. 예를 들어 개발 DefaultAzureCredential 중에 Azure CLI를 통해 로그인하는 데 사용하는 자격 증명과 같은 개발자 도구 자격 증명을 사용하거나 Azure에서 호스트되는 앱의 경우 관리 ID사용할 수 있습니다. 자세한 내용은 Python용 Azure SDK를 사용하여 Azure 서비스에 Python 앱 인증을 참조하세요.

5. Blob 만들기 확인

두 방법 중 하나의 코드를 실행한 후 Azure Portal로 이동하여 Blob 컨테이너로 이동하여 sample-source.txt 파일과 동일한 내용이 있는 sample-blob-{random}.txt 명명된 새 Blob이 있는지 확인합니다.

업로드된 파일을 보여 주는 Blob 컨테이너에 대한 Azure Portal 페이지

명명AZURE_STORAGE_CONNECTION_STRING된 환경 변수를 만든 경우 Azure CLI를 사용하여 az storage blob list 명령을 사용하여 Blob이 있는지 확인할 수도 있습니다.

az storage blob list --container-name blob-container-01

암호 없는 인증을 사용하는 지침을 따른 경우 스토리지 계정에 대한 연결 문자열 사용하여 이전 명령에 매개 변수를 추가할 --connection-string 수 있습니다. 연결 문자열 얻으려면 az storage account show-connection-string 명령을 사용합니다.

az storage account show-connection-string --resource-group PythonAzureExample-Storage-rg --name pythonazurestorage12345 --output tsv

전체 연결 문자열 매개 변수의 값 --connection-string 으로 사용합니다.

참고 항목

Azure 사용자 계정에 컨테이너에 "Storage Blob 데이터 기여자" 역할이 있는 경우 다음 명령을 사용하여 컨테이너의 Blob을 나열할 수 있습니다.

az storage blob list --container-name blob-container-01 --account-name pythonazurestorage12345 --auth-mode login

6. 리소스 정리

이 예제에서 사용된 리소스 그룹 및 스토리지 리소스를 유지할 필요가 없는 경우 az group delete 명령을 실행합니다. 리소스 그룹은 구독에서 진행 중인 요금이 발생하지 않지만 리소스 그룹의 스토리지 계정과 같은 리소스에는 요금이 계속 부과될 수 있습니다. 적극적으로 사용하지 않는 그룹을 정리하는 것이 좋습니다. 인수 --no-wait 를 사용하면 작업이 완료되는 것을 기다리는 대신 명령이 즉시 반환됩니다.

az group delete -n PythonAzureExample-Storage-rg  --no-wait

ResourceManagementClient.resource_groups.begin_delete 메서드를 사용하여 코드에서 리소스 그룹을 삭제할 수도 있습니다. 예제: 리소스 그룹 만들기의 코드는 사용량을 보여 줍니다.

암호 없는 인증을 사용하는 지침을 따른 경우 만든 애플리케이션 서비스 주체를 삭제하는 것이 좋습니다. az ad app delete 명령을 사용할 수 있습니다. <AZURE_CLIENT_ID> 자리 표시자를 서비스 주체의 앱 ID로 바꿉니다.

az ad app delete --id <AZURE_CLIENT_ID>

참고 항목