Managed Service Identity (MSI) を使用して、App Configuration と接続する構成をとる場合、ローカル環境でも DefaultAzureCredential
を使用していれば、問題なく動くはずなのですが
不思議な挙動に悩まされたので、備忘録を残します。
環境及び構成
- Visual Studio 2022 (v.17.1.3)
- Azure Functions (v4、in-process)
前提条件
- ローカルからの認証に使用する Azure のアカウントには、
App Configuration Data Reader
ロールを付与済み - Visual Studio には、対象の
App Configuration Data Reader
ロールが付与済のアカウントでログイン済み
実装したソースコード
builder.ConfigurationBuilder.AddAzureAppConfiguration(o => { var connectionString = defaultConfig["AppConfig:ConnectionString"]; if (string.IsNullOrWhiteSpace(connectionString)) { var endpoint = new Uri(defaultConfig["AppConfig:Endpoint"]); o.Connect(endpoint, new DefaultAzureCredential()); } else { o.Connect(connectionString); } var context = builder.GetContext(); o.Select("*"); });
当初期待していた挙動
- Visual Studio の認証情報を使用して、App Configuration への接続が認証され、App Configuration から設定情報が取得できる
実際の挙動
- 認証エラーが返却される(401)
対処方法
- Azure CLI のログイン情報で、デフォルトのサブスクリプションを対象の App Configuration が含まれるサブスクリプションへ変更する
DefaultAzureCredential
が使用するテナント Id を指定する
デフォルトのサブスクリプションを切り替える
自分のアカウントは、複数のサブスクリプションに所属している + 今回接続したかったサブスクリプションがデフォルトのサブスクリプションに設定されていませんでした。
なので、まずデフォルトのサブスクリプションを設定しました。
az account set --subscription {サブスクリプション Id}
これでデフォルトのサブスクリプションが切り替わります。 この状態で、Function App を実行してみます。
Function App の実行結果
- 認証エラーが返却される(401)
最初と同じ挙動です。
DefaultAzureCredential
が使用するテナント Id を指定する
次に、Function App 側で、認証に行くテナントを直接指定します。
2パターン設定方法がありますので、好きな方法で指定します。
パターン1
DefaultAzureCredential
の引数として、オプションにテナント Id を指定する方法です。
builder.ConfigurationBuilder.AddAzureAppConfiguration(o => { var connectionString = defaultConfig["AppConfig:ConnectionString"]; if (string.IsNullOrWhiteSpace(connectionString)) { var endpoint = new Uri(defaultConfig["AppConfig:Endpoint"]); o.Connect(endpoint, new DefaultAzureCredential(new DefaultAzureCredentialOptions { VisualStudioTenantId = "{{テナント Id}}" })); } else { o.Connect(connectionString); } var context = builder.GetContext(); o.Select("*"); });
パターン2
local.settings.json に AZURE_TENANT_ID
を設定する
{ "IsEncrypted": false, "Values": { //--- Development "AppConfig:ConnectionString": "", "AppConfig:Endpoint": "", "AZURE_TENANT_ID": "テナント Id", } }
Azure 上では、このテナント Id を指定する必要はないので、個人的には、ソースコードを変更せずに済むこちらを使用しました。
設定が終わったら、Function App を実行します。
Function App の実行結果
- 接続成功
テナント Id を指定した状態で、Azure CLI のデフォルトサブスクリプションを他のものに切り替える
次に、テナント Id を Function App で指定した状態で、Azure CLI の設定を元に戻します。
設定は、先ほどの az account set ~
で関係のないサブスクリプション Id を指定してみます。
変更したら、Function App を実行します。
Function App の実行結果
- 認証エラーが返却される(401)
この挙動を見るに、Visual Studio + Function App の構成で MSI をローカルで使用したい場合、Azure CLI の設定 + テナント Id の指定が必要なようです。
まとめ
これバグなのでは?