ごった煮

色々な事を書いてます

Azure FunctionsでAzure App Configurationを使う

Azure App Configurationは、既に.NET Core、.NET Frameworkに対応したクラスライブラリが提供されているのでFunction Appでもすぐに使用できます。

簡単に使用できるので覚えておくと便利かと思います。

実装する

前提条件

  • Azure App Configurationのリソースを作成済み
  • 最新のFunctions toolsをインストール済み

パッケージのインストール

以下のパッケージをNuGetからインストールします。

Microsoft.Extensions.Configuration.AzureAppConfiguration

App Configurationで設定を作る

ポータル > アプリ構成 > キー値のエクスプローラー で設定します。 f:id:papemk2:20190228221326p:plain

ラベルは、何も設定しないと「ラベルなし」になります。 特にラベル作成用の画面がないので、最初戸惑うかもしれませんが、ラベルのテキストボックスにテキストを入れて、設定を作成するとラベルも一緒に作成されます。

一度ラベルが作成されると、次回からラベルのテキストエリアで作成済みのラベルが選択できます。 また、ラベルが選択できる状態でも同じようにテキストエリアにテキストを入力するとラベルが追加されます。 f:id:papemk2:20190228221632p:plain

通常設定を追加すると以下のように表示されます。 f:id:papemk2:20190228221733p:plain

同じ名前のキーに異なるラベルを付けて作成すると、同一キーでまとめて表示してくれます。 キーの横にある三角マークで展開できます。 f:id:papemk2:20190228221955p:plain

アプリを実装する

Function Appは、v2.xを使用します。

一番シンプルな実装

[FunctionName("Function1")]
public static void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log)
{            
    var builder = new ConfigurationBuilder();
    builder.AddAzureAppConfiguration("接続文字列");

    var config = builder.Build();
    log.LogInformation(config["キー名"]);
}
builder.AddAzureAppConfiguration("接続文字列")

を呼び出すと、これだけで設定を読み込む準備が完了します。 あとは、通常のIConfigurationを使うのと同じ感覚で設定の読み込みができます。

この実装では、ラベルを指定していません。 そのためこれで取得できるのは、ラベルを設定していない設定に限ります。

ラベル付きの設定を取得する

ラベルを指定して設定を読み込む場合は、AddAzureAppConfigurationで読み込む設定を指定します。 以下のような感じです。

builder.AddAzureAppConfiguration(_ =>
    _.Connect("接続文字列")
    .Use("キー名", "ラベル名")
);

var config = builder.Build();

log.LogInformation(config["キー名"]);

これで指定した設定を読み出せます。

設定の変更を検知する

App Configurationは、アプリケーションの再起動なしに設定の変更を反映する仕組みを備えています。

以下のようにWatchメソッドに登録すると、設定したTimeSpanの時間でポーリングをして変更を監視してくれます。

builder.AddAzureAppConfiguration(_ =>
    _.Connect("接続文字列")
    .Watch("Config:Test", "Staging", TimeSpan.FromSeconds(1))
    .Use("Config:Test", "Staging")
);

var config = builder.Build();

while (true)
{
    var value = config["Config:Test"];

    log.LogInformation(value);
    Thread.Sleep(10000);
}

ループ中に設定を変更すると、変更されることが確認できます。

特定の設定を変更したらすべて再読み込みさせる

設定変更の監視に近い機能で、特定の設定が変更されたらすべての変更を再読み込みする設定も可能です。

builder.AddAzureAppConfiguration(_ =>
    _.Connect("接続文字列")
    .WatchAndReloadAll("Config:Test", "Staging", TimeSpan.FromSeconds(1))
    .Use("Config:Test", "Staging")
    .Use("Config:Test2", "Staging")
);

var config = builder.Build();

while (true)
{
    var value = config["Config:Test"];
    var value2 = config["Config:Test2"];

    log.LogInformation(value);
    log.LogInformation(value2);
    Thread.Sleep(10000);
}

上記のソースコードで、WatchAndReloadAllに設定していない値を変更しただけだと値は何も変更されないが、そのあとにWatchAndReloadAllに設定した値を変更すると、 変更した値がすべて変更される動きが確認できます。

まとめ

特に難しい実装をせずにApp Configurationから設定を読み出しができました。

アプリの再起動なしで設定を変更する機能は、結構使えるシナリオがあるかなと思います。 ですが、例えばRedisなどでコネクションを張っている状態で接続文字列を差し替えたりした場合など不用意に差し替えをすると危なそうなシナリオも考えられるので慎重に扱う方が良さそうです。

また短い時間での大量な設定に対するポーリングや、全件差し替えを行うと結構コストが高そうなので、その点も考慮が必要かもしれません。