2020/8 の Azure Functions Live でかなりインパクトの大きいアップデートについて話があったので、触れておきたいと思います。Azure Functions でイマイチだと思っていた部分がかなり改善されているので、今後は使うのが当たり前になりそうな機能ばかりです。
例によって自分の興味ある部分しか触れないので、YouTube で本編をちゃんと見ておいた方が良いです。
新機能と今後の予定でいくつか紹介されていますが、以下の 6 つに絞って試した結果をまとめておきます。まだ何も公開されていなさそうですが、OAS から Function を作るのは結構面白そうです。
- ReadyToRun
- IFunctionConfigurationBuilder
- Per app scale limits for all plans
- Durable Functions monitoring in portal
- Restrict storage to VNet
- Checkpoint control for Event Hubs / Cosmos DB
特に Configuration や Checkpoint control などは全ユーザー待望だと思うので嬉しいです。
ReadyToRun
Tiered Compilation は Function Host では有効化されていませんが、Function App での ReadyToRun 済みアセンブリの読み込みに対応したようです。Function Host 自体は R2R でビルドされています。
実際にどのくらいの効果があるかは検証中ですが、原理上は悪くなることはないかなと思っています。規模の大きい Function の方が効果が出やすそうです。
この辺りの情報は以前書いたので適当に参照しておいてください。
ドキュメントにあるように csproj に 2 つ設定を追加すると、発行時に自動的に ReadyToRun 済みのアセンブリを作成してくれます。R2R には多少時間はかかりますが、最近のマシンだと無視できるレベルでしょう。
csproj に単純に足すと、デバッグ実行時にも ReadyToRun を行ってしまうので、CI などで dotnet publish
の実行時のみ ReadyToRun 済みアセンブリを作成するという戦略が良いでしょう。
以下のような単純なコマンドで ReadyToRun を行いつつビルドできます。
dotnet publish -c Release -o ./publish -r win-x64 -p:PublishReadyToRun=true
ドキュメントでは RID として win-x86
を使っていますが、Function SDK に問題がありインストールされている .NET Core の bitness に合わせないと正常にビルド出来ません。
原因は extensions.json
の生成時にアセンブリを読み込む仕組みになっていますが、当然ながら bitness の違う ReadyToRun アセンブリは読み込めないためです。
殆どの開発者は x64 版 .NET Core をインストールしているはずなので、RID は win-x64
を指定する必要があるということです。解決には時間がかかりそうな気がします。
IFunctionConfigurationBuilder
Azure Functions ユーザー待望の Configuration カスタマイズ機能がついに提供されました。
これで ASP.NET Core でお馴染みの appsettings.json
を使って設定を自由に読み込めるようになりました。local.settings.json
は特殊なのでオブジェクトを書けなくて結構辛かったです。
App Service Plan 以外で Binding / Trigger の接続文字列などを変更しようとすると、Azure Portal に以下のようなエラーが表示されて Function Host が起動しなくなります。
これは Scale Controller が外にいる構造上、仕方ない挙動です。ただし Premium Plan + Runtime Scale Monitoring が有効なら Scale Controller がリソースにアクセスする必要が無いので、このあたりの制限を緩和出来ないか提案をしています。
制限が緩和されれば VNET Integration を使いつつ、Key Vault に Service Endpoint or Private Endpoint を追加してアクセス元を絞ることが出来るようになるはずです。
ドキュメントなどでは IFunctionsConfigurationBuilder
が待望の機能過ぎて扱いが雑になっていますが、今回 FunctionsHostBuilderContext
というクラスも追加されて、Startup
内で以下の情報を簡単に参照できるようになりました。
ApplicationRootPath
Configuration
EnvironmentName
特に ApplicationRootPath
と Configuration
を触れるようになったのは、非常にありがたいです。
これにより Startup
内の Options パターンが非常に扱いやすくなっています。正直なところ、これまで IConfiguration
を取る手段がなかったのがハードモード過ぎました。
拡張メソッドとして用意された GetContext
を呼び出すと、Configure
とConfigureAppConfiguration
の両方で参照できます。
public class Startup : FunctionsStartup { public override void Configure(IFunctionsHostBuilder builder) { var context = builder.GetContext(); builder.Services.Configure<SampleOptions>(context.Configuration.GetSection("Sample")); } } public class SampleOptions { public string Value { get; set; } }
これですっきりしましたね。自分で ConfigurationBuilder
を使って組み立てる必要が無くなったのはかなり良いです。これでやっと DI をフルに使った Azure Functions の開発が行いやすくなった感あります。
ただし Configuration
の値は ConfigureAppConfiguration
の時点では完全な情報ではありませんので、Key Vault を参照する場合は ASP.NET Core の場合と同様に一度 Build
する必要があります。
public class Startup : FunctionsStartup { public override void Configure(IFunctionsHostBuilder builder) { } public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder) { var builtConfig = builder.ConfigurationBuilder.Build(); var tokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback)); builder.ConfigurationBuilder.AddAzureKeyVault(builtConfig["KeyVaultEndpoint"], keyVaultClient, new DefaultKeyVaultSecretManager()); } }
これで Key Vault に保存された Secret を Managed Identity を使って読み込むことが出来ます。
App Service に用意されている Key Vault Reference では Service Endpoint / Private Endpoint を越えられませんが、アプリからの場合は問題なくアクセス出来ます。
Per app scale limits for all plans
これまでも WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT
という設定がプレビューで提供されていましたが。新しくちゃんと動く設定が追加されたようです。
All plans と言っているので App Service Plan でも使えそうな気がしますが、軽く試した感じではちゃんと動いてなさそうでした。Consumption / Premium Plan 限定かもしれません。
ドキュメントにあるように SQL Database など接続数の上限が存在するサービスを利用する場合に、スケールアウトの上限を設定できるのは安心という感じです。
Durable Functions monitoring in portal
Durable Functions を使っている人にとっては待望の Orchestrator のモニタリングが Azure Portal で行えるようになりました。モニタリングのソリューションはいくつかありましたが、どれも決定打に欠けました。
今回のリリースで Azure Portal から設定不要でモニタリング出来るようになったのはかなり大きいです。
既に完了している Orchestrator についても Running と表示されていますが、正直大した問題ではありません。使われている KQL が修正されれば終わるような話です。
一覧から日付を選ぶと、Orchestrator の実行ログをさらに細かく見ることが出来ます。この辺りはフィードバックで良くなっていく部分だろうと思います。
Azure Portal に組み込まれたという点が非常に重要なので、これからの進化に期待しています。
Restrict storage to VNet
Function App のバックエンドで使われている Storage Account に対して、Service Endpoint や Private Endpoint でアクセス制限を行うと正しく動作しない問題があります。
ドキュメントにも Storage Account に対して Service Endpoint を追加しないように書かれています。
Service Endpoint に関しては使えるようになっている気がします。対応済みかもしれません。
とはいえ App Service の Regional VNET Integration は他のサービスに比べて挙動が特殊なことが多いので、事前に動作確認をしておく必要があります。
特に Private Endpoint が絡むとさらに複雑になる傾向にあります。
Checkpoint control for Event Hubs / Cosmos DB
Checkpoint control と言ってはいますが、早い話リトライについてです。Function 自体にはそもそもリトライという概念はなく、Queue でのメッセージ再追加や Event Grid 側のリトライに任せるなど、外部サービスを使う形で行われていました。
特に困っていたのが Cosmos DB で、Change Feed の処理が失敗した場合にはリトライなどは行われず、そのまま次の処理に進んでしまう問題がありました。それが以下の PR で解消されようとしています。
というか、何故失敗しているのに Change Feed が先に進むのだという感想しかないですが、これまではアプリケーション側にリトライを実装するという形で乗り切ってきたのが不要になります。
設計としては外部サービス側にリトライを任せた方が美しいですが、現実問題として Event Hubs と Cosmos DB の場合はどうしようもなかったということでしょう。割と待望の機能です。