しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Functions の Python V2 と Node.js V4 プログラミングモデルを利用する上での注意点

去年に GA してから時間が経過しましたが、Azure Functions の新しいプログラミングモデル Python V2 と Node.js V4 を使う機会が増えてきて、以前書いたエントリからの更新点も増えたので簡単にまとめます。

プレビュー中に書いたエントリは以下になりますが、基本的な部分は変わっていないはずです。

新しいプログラミングモデルは非常に扱いやすく、これまでのように function.json を手動で書く必要がないのでミスを減らすことが出来ますが、内部的には function.json と同様の仕組みが使われているのでエラーメッセージなどで混乱するかもしれません。実行時エラーで function.json に関するメッセージだった場合にはバインディングとトリガー周りの設定ミスと考えてください。

Python V2 と Node.js V4 について GA してドキュメントとツールのサポートがしっかりと整備されたので、まずはその辺りについて触れていきます。その後に注意点をいくつか紹介します。

Python V2 プログラミングモデル

Python V2 は今年の 5 月に GA していて、既に十分安定していると言っても良いレベルになっていますが、一部のトリガーのテンプレートやドキュメントは追従できていない部分があるため、V1 と V2 どちらのプログラミングモデル向けなのかを確認する必要があります。

Azure Functions を Python で作成する際には VS Code を使うことが大半だと思います。最新の Azure Functions 拡張を入れておくと以下のように新規作成時に Model V2 を選択できるようになっていますが、まだテンプレートは全てのトリガー向けに用意されていません。Azure Functions Core Tools を使っても同じことが可能になっていますが、こちらの方がテンプレートの種類が多い印象です。

VS Code にテンプレートが用意されていないバインディングやトリガーは、今のところはドキュメントを確認して手動で追加する形になると思います。特によく使いそうな Cosmos DB Trigger はまだテンプレートが用意されていないので面倒です。

ドキュメントも V1 と V2 でタブが用意されているので、確実に V2 が選択されていることを確認してから参照してください。書き方がかなり異なっているので間違えることは少ないと思いますが、検索で辿り着くと V1 向けで表示されることもあるので注意です。

Python については Blueprint という概念が追加されていて、少し他の言語とは毛色が異なっている部分もあるので、一度は実際に触って書き方を試しておくのが良いかと思います。

Node.js V4 プログラミングモデル

Python V2 に比べるとリリースが遅れた Node.js V4 ですが、こちらもプレビューを長い期間取っていたので、既にかなり安定していると感じています。書き味としては Express のようなスタイルなので、Node.js を使った開発に慣れている方ならスムーズに利用できると思います。

Node.js V4 も Python V2 と同様に VS Code と最新の Azure Functions 拡張を入れておけば、新規作成時に Model V4 を選ぶことが出来るので簡単に始めることが出来ます。

テンプレートについては Python V2 よりも Node.vs V4 の方が数が多いので、これまで V3 で開発していた人も困ることはないと思います。ドキュメントも V4 がデフォルトで提供されているので、こちらもバージョンを間違えないように注意して読んでください。

ちなみに Node.js V4 についてはマイグレーションのドキュメントが公開されているので、既存の Node.js V3 の Function があれば早めに Node.js V4 へ移行しておいた方が開発が楽になります。

ドキュメントでは V3 と V4 の例が紹介されているので、どのように書き換えればよいのか分かりやすくなっています。そして V4 でどれだけシンプルに書けるようになったかも一目瞭然なので、Azure Functions を Node.js で開発している方は必読だと思います。

最新の Azure Functions Runtime では AzureWebJobsFeatureFlags が不要に

これまで function.json というファイルを手書きする必要があったのを、実行時に各言語ワーカーから受け取る仕組みが追加されたことで、Python と Node.js の開発体験が劇的に向上したのですが、その仕組みがデフォルトで有効化されていないため AzureWebJobsFeatureFlags という設定を追加する必要がありました。

しかし、少し前のコミットでデフォルト有効化するコードが追加され、その実装はバージョン 4.28.0 に含まれているため、このバージョンより新しい Azure Functions Runtime では設定が不要になっています。

自分が確認した限り、大半のリージョンでは 4.28.3 がデプロイされているので設定なしで動作するようになっていますが、一部のリージョンでは 4.27.5 が残っているのと Azure Functions Core Tools が 4.27.5 ベースになっているので、暫くは AzureWebJobsFeatureFlags を明示的に指定しておいた方が安全です。

恐らく今月中には全てのリージョンに 4.28.3 がデプロイされるのではないかと思っています。

Cosmos DB Extension v3 と v4 の混在に注意

これまで Azure Functions ではバインディングやトリガーで使われている SDK のアップデートはあっても、破壊的変更は行われてこなかったのですが Cosmos DB Extension については SDK 側で破壊的変更が多かったため、Azure Functions 側でも Cosmos DB Extension の v3 と v4 の両方が扱えるように実装されました。

C# であれば以前ブログに書いた通り NuGet パッケージを更新して、コンパイルが通らなくなったプロパティ名を修正するぐらいで済むのですが、Python や Node.js では少し罠があります。

具体的に見ていくと、Python V2 の場合はこれまでのバインディングとトリガーでは Cosmos DB Extension の v4 向けの設定となっていて、新しく v3 向けにバインディングとトリガーを追加することでユーザー側がアップデートのタイミングをコントロールできるようになっています。

参考情報になりますが、この実装が追加された PR は以下になります。プロパティ名は Cosmos DB Extension v4 準拠になっているため、Collection が Container になっているなどいくつか変更されています。

Python V2 と同じように Node.js V4 でも Cosmos DB Extension v3 と v4 をユーザー側で選べるようになっていますが、実装が Union 型を使っているためプロパティ名によって型推論の結果が変化し、Cosmos DB Extension v3 と v4 が切り替わるようになっています。

入力補完の結果としては最初は同じようなプロパティが出てきて混乱しますが、最初に connectionconnectionStringSetting を指定するようにすると分かりやすくなります。具体的には前者を使用すると v4 になり後者を使用すると v3 になります。

この辺りの型宣言は以下のファイルで定義されています。この辺りは TypeScript の機能を使って上手く実装した感がありますが、評価が分かれそうな予感です。

こちらも Collection が Container に変更されているので、利用する際にはプロパティ名を間違えないように注意してください。TypeScript ではチェックが走るはずですが JavaScript では素通りになるはずです。

Cosmos DB Extension v4 への Python V2 / Node.js V4 側での対応は以上になりますが、v3 と v4 の切り替えには Azure Functions の Extension Bundle も深く関わっています。Function 実装側で Cosmos DB Extension v4 を使うようにしても、Extension Bundle が古いままでは実行時エラーとなり動作しません。v4 を使う際には Extension Bundle のバージョンも v4 以上に更新する必要があります。

{
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

一部の言語向けではテンプレートから作成すると Extension Bundle v3 が使われる設定になっているため、Cosmos DB Extension v4 向けの Function を追加すると実行時エラーとなります。

Extension Bundle に含まれている拡張機能のバージョンは GitHub のリリースから確認出来ます。Cosmos DB Extension v3 と v4 が共存できないため Extension Bundle のバージョンで切り替えを行う必要があります。

C# で開発している場合には意識することは無いので忘れがちですが、Python や Node.js では Extension Bundle がかなり重要なのでバージョンには気を付ける必要があります。

Static Web Apps の Managed Functions 上での利用について

通常の Azure Functions であれば Consumption Plan であっても、設定だけ追加してしまえば問題なく Python V2 / Node.js V4 で実装したアプリケーションをデプロイして実行できますが、Static Web Apps に付属している Managed Functions では AzureWebJobs から始まるキーの設定は禁止されているので、これまでは以下の Issue にもあるようにどう頑張っても実行できませんでした。

しかし前述した通り、Azure Function Runtime 側でデフォルト有効になるように変更されたため、特定のバージョン以降がデプロイされたリージョンでは Python V2 / Node.js V4 の実行をサポートしています。

確認した限りでは East Asia では 4.28.3.21820 がデプロイされているので、以下のような Node.js V4 を使った Function を Managed Functions として実行出来ます。

実際に上の Function をデプロイしてみましたが、以下のように問題なくデプロイが行えて Azure Portal からも認識されています。Azure Functions Runtime のバージョンが古かった時はデプロイは出来ても実行は出来ず、Azure Portal からもデプロイした Function が認識されないという状態でした。

全リージョンに展開されているのかは確認していませんが、恐らく一部のリージョンでは古いバージョンが残っていると思われるので注意は必要ですが、よく使われるであろう East Asia では問題なく使えそうです。