タイトルの通りですが、ASP.NET Core と一緒に追加された Configuration 周りは Provider を実装すると簡単に拡張できるようになっているので、実際に Azure Table Storage 向けの実装を書いて試してみました。
流れとしては以下の 2 つを継承したクラスを実装するだけなので簡単です。
- IConfigurationSource
- ConfigurationProvider
Configuration 周りは同期処理として実行されるので、Task ベースの非同期とか使ってる場合には、デッドロックしないように ConfigureAwait(false)
を付けたりと工夫が必要です。
サンプルに近い実装ですが、とりあえず GitHub に一式を公開しておきました。
デフォルトでは Key Vault 向け Provider が入っているのでそれを使えば良いという感じはしますが、Key Vault では ":" での区切りではなく "--" になったり、接続文字列以外のセキュリティが求められないパラメータ的なものまで入れるのは無駄な感じもします。
何より Azure Table は安くて容量も大きいので、使いどころはあるのではないかなと思います。
Provider 周りの実装は GitHub を見てもらうとして、残りはちょっとだけ設定周りについて書いておくことにします。この Provider は Azure Storage の接続文字列が必要になるので、Program.cs にある IWebHostBuilder
のメソッド内で接続文字列を config から取得するようにします。
public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { var builtConfig = config.Build(); config.AddAzureTableStorage(builtConfig.GetConnectionString("StorageConnection"), builtConfig["TableName"], builtConfig["PartitionKey"]); }) .UseStartup<Startup>(); }
デフォルトのファイルや環境変数からの設定後の値が ConfigureAppConfiguration
のタイミングで取れるので、それを利用して Azure Storage の Provider を追加しています。
appsettings.json には以下のように書いていますが、TableName と PartitionKey はセクションにしても良いかもしれません。これらの設定は App Service の場合は App Settings からオーバーライド出来るので便利です。
{ "TableName": "Config", "PartitionKey": "Primary", "ConnectionStrings": { "StorageConnection": "STORAGE_CONNECTION_STRING" } }
この辺りの考え方は Key Vault の時と同じです。というかドキュメントに書いてあります。
テーブル名やプライマリキーは設定から読んでも良いし、固定値にしても良いと思います。Table の構造としては RowKey を Configration 内で参照するためのキーとして扱うようになっています。
なので Table には以下のような形でデータを投入することになります。
後は実際にConfiguration から値を読み込むのですが、今回は Configure
を使ってオプション値として扱ってみました。以下のようなコードを書くとセクション内の値をバインドしてくれます。
services.Configure<CustomModel>(Configuration.GetSection("Custom"));
コンストラクタインジェクションを使って受け取ったクラスには、ちゃんと Table Storage に書き込んだ値が入っていることが確認出来ます。
Table Storage はツールが充実しているので、Azure Portal からポチポチ設定するより楽かもしれませんね。
フレームワーク側にデフォルトの実装がある程度用意されているので、カスタマイズは思ったよりも簡単でした。是非はともかく SQL Server や Cosmos DB などをソースとする Provider も実装も出来るはずです。
デフォルトの実装は非常に参考になるので、カスタマイズの際には参考にするとよい感じです。
Azure の場合は Key Vault で大体解決すると思いますが、AWS Secrets Manager や HashiCorp Vault などに対応した Provider は価値がありそうです。*1
*1:既にありそうな気もしますが調べてないです