0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

.NET 8 コンソールアプリから Blob コンテナーへのアクセスを VM のマネージド ID 権限で試してみた

Posted at

Azure Storage Account へのアクセスはアクセスキーを使うと簡単なのですが、アクセスキーが漏洩すると大変です。そこで今回は、Azure 仮想マシンのマネージド ID 権限で Blob コンテナー一覧を表示する .NET 8 コンソールアプリで試してみました。

検証用の Azure Storage Account と コンテナーを 2 つ作成

bash
prefix=mnrblob
region=japaneast

az group create \
  --name ${prefix}-rg \
  --location $region

az storage account create \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --sku Standard_LRS

az storage container create \
  --account-name ${prefix} \
  --name test-container-01 \
  --auth-mode login

az storage container create \
  --account-name ${prefix} \
  --name test-container-02 \
  --auth-mode login

az storage container list \
  --account-name ${prefix} \
  --auth-mode login \
  --output table

Name               Lease Status    Last Modified
-----------------  --------------  -------------------------
test-container-01                  2024-11-29T23:02:28+00:00
test-container-02                  2024-11-29T23:02:47+00:00

ローカルで Blob コンテナー一覧を表示する .NET 8 コンソールアプリを作成

bash
dotnet new console -o $prefix --use-program-main

cd $prefix

dotnet add package Azure.Storage.Blobs

dotnet add package Azure.Identity

export AZURE_STORAGE_ACCOUNT_NAME=$prefix

code Program.cs
Program.cs
using System;
using System.Threading.Tasks;
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;

class Program
{
    static async Task Main(string[] args)
    {
        try
        {
            string accountName = Environment.GetEnvironmentVariable("AZURE_STORAGE_ACCOUNT_NAME") ?? "";

            var blobServiceClient = new BlobServiceClient(
                new Uri($"https://{accountName}.blob.core.windows.net"),
                new DefaultAzureCredential());

            await foreach (BlobContainerItem container in blobServiceClient.GetBlobContainersAsync())
            {
                Console.WriteLine($"Container name: {container.Name}");
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex.Message}");
        }
    }
}

ローカルで動作確認

bash
dotnet run

Container name: test-container-01
Container name: test-container-02

Azure CLI をログアウトして動作確認

bash
az logout

dotnet run

認証済み情報がなくなったので、以下のメッセージが表示されました。

Exception: DefaultAzureCredential failed to retrieve a token from the included credentials. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/defaultazurecredential/troubleshoot
- EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot
- WorkloadIdentityCredential authentication unavailable. The workload options are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/workloadidentitycredential/troubleshoot
- ManagedIdentityCredential authentication unavailable. No response received from the managed identity endpoint.
- Visual Studio Token provider can't be accessed at /Users/mnr/.IdentityService/AzureServiceAuth/tokenprovider.json
- Please run 'az login' to set up account
- PowerShell is not installed.
- Azure Developer CLI could not be found.

検証用の Azure 仮想マシンを作成

bash
az login

az vm create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --os-disk-name ${prefix}-vmOSDisk \
  --image Canonical:ubuntu-24_04-lts:server:latest \
  --size Standard_B1s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --assign-identity \
  --nsg-rule NONE \
  --public-ip-address-dns-name ${prefix}

az network nsg rule create \
  --resource-group ${prefix}-rg \
  --name Allow-SSH \
  --nsg-name ${prefix}-vmNSG \
  --priority 100 \
  --source-address-prefixes $(curl -s inet-ip.info) \
  --destination-port-ranges 22 \
  --access Allow \
  --protocol Tcp

別ターミナルで Azure 仮想マシンに SSH 接続

bash
prefix=mnrblob
region=japaneast

ssh azureuser@${prefix}.$region.cloudapp.azure.com

sudo apt-get update

sudo apt-get install -y dotnet-sdk-8.0

dotnet --version

prefix=mnrblob

dotnet new console -o $prefix --use-program-main

cd $prefix

dotnet add package Azure.Storage.Blobs

dotnet add package Azure.Identity

export AZURE_STORAGE_ACCOUNT_NAME=$prefix

cat <<EOF > Program.cs
using System;
using System.Threading.Tasks;
using Azure.Identity;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;

class Program
{
    static async Task Main(string[] args)
    {
        try
        {
            string accountName = Environment.GetEnvironmentVariable("AZURE_STORAGE_ACCOUNT_NAME") ?? "";

            var blobServiceClient = new BlobServiceClient(
                new Uri($"https://{accountName}.blob.core.windows.net"),
                new DefaultAzureCredential());

            await foreach (BlobContainerItem container in blobServiceClient.GetBlobContainersAsync())
            {
                Console.WriteLine($"Container name: {container.Name}");
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex.Message}");
        }
    }
}
EOF

dotnet run

まだ、マネージド ID 権限を付与していないので、以下のエラーメッセージが表示されました。

Exception: This request is not authorized to perform this operation using this permission.
RequestId:899451a0-b01e-0016-56b6-423fc8000000
Time:2024-11-29T23:26:32.7651261Z
Status: 403 (This request is not authorized to perform this operation using this permission.)
ErrorCode: AuthorizationPermissionMismatch

Content:
<?xml version="1.0" encoding="utf-8"?><Error><Code>AuthorizationPermissionMismatch</Code><Message>This request is not authorized to perform this operation using this permission.
RequestId:899451a0-b01e-0016-56b6-423fc8000000
Time:2024-11-29T23:26:32.7651261Z</Message></Error>

Headers:
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 899451a0-b01e-0016-56b6-423fc8000000
x-ms-client-request-id: 6695cfae-b890-4cbe-8d92-9fd46a08e176
x-ms-version: 2025-01-05
x-ms-error-code: AuthorizationPermissionMismatch
Date: Fri, 29 Nov 2024 23:26:31 GMT
Content-Length: 279
Content-Type: application/xml

元のターミナルで仮想マシンの マネージド ID に Storage Account Contributor 権限を付与

bash
az role assignment create \
  --role "Storage Account Contributor" \
  --assignee $(az vm show \
    --resource-group ${prefix}-rg \
    --name ${prefix}-vm \
    --query identity.principalId \
    --output tsv) \
  --scope $(az storage account show \
    --name ${prefix} \
    --resource-group ${prefix}-rg \
    --query id \
    --output tsv)

もう一度、仮想マシンで動作確認

bash
dotnet run

Container name: test-container-01
Container name: test-container-02

後片付け

bash
az group delete \
  --name ${prefix}-rg \
  --yes

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?