Visual Studio 2017 の 15.8 で Azure Functions の Zip Deploy と Run-From-Zip に対応したので、そろそろちゃんとブログにまとめておこうかと思いました。
デプロイのタスク定義は Azure Functions の SDK に含まれているので、他のプロジェクトでは Zip Deploy は使えないので注意。
Zip Deploy は名前の通り zip ファイルを渡すと、それをそのままデプロイしてくれる機能です。これまでは Web Deploy 形式として作成しないといけなかったのですが、zip ならどの環境でも簡単です。
特に CI/CD を使う場合には有用ですね。MS Deploy はオプションが少し複雑です。
そして Run-From-Zip は zip ファイルをそのまま wwwroot 以下にマウントして実行に使ってしまうという、App Service の謎テクノロジーです。GitHub の Issue は非常に長くディスカッションが続いています。
Azure Functions の起動や実行が遅いのは、主にストレージが Azure Files が使われていて、通常の App Service よりもファイル I/O に対しては低速になっているのが原因です。
それに対して Run-From-Zip は App Service の起動時に zip をインスタンスのローカルストレージに落としてきて、それをマウントしているみたいなので Azure Files の I/O に引っ張られません。そしてローカルストレージは高速なので全体的なパフォーマンスが改善するというからくりです。
Run-From-Zip はこれまでのデプロイと比較して、以下のような点で優れていると言われています。
- パフォーマンス改善
- デプロイ
- スタートアップ
- デプロイのアトミック性
- マウントする zip を切り替えるだけなので
- バージョニング
バージョン管理はストレージ上に zip の履歴を持っているので、packagename.txt の中身を書き換えて App Service を再起動すればそのバージョンがデプロイされるという仕組みです。
この zip を最大いくつ保持してくれるのかは謎ですが、Visual Studio からデプロイするとファイル名がローカル時間のタイムスタンプになるのが少し気になります。
実際に Azure Functions を Run-From-Zip としてデプロイしてみます。15.8 がインストールされていれば、発行先の選択時に「ZIP から実行」というチェックボックスが増えているので、それにチェックを入れます。
その後はこれまで通りにデプロイ先を指定すれば、Zip Deploy 用の発行プロファイルが作成されます。
発行を実行すると、数秒でビルドからデプロイまで完了します。
デプロイの結果は Kudu のメニューから「Zip Push Deploy」を選べば最新の情報を確認出来ます。
Visual Studio からのデプロイに対応したので、これまでと同じように違和感なく使えるようになって良い感じです。まだプレビューという点だけは気になりますが、推奨されているので大丈夫でしょう。
Run-From-Zip は主に Azure Functions 用みたいに紹介されていますが、仕組み自体は Functions に依存するものではないので通常の Web App でも利用することが出来ます。
使い方は非常に簡単で、WEBSITE_RUN_FROM_ZIP
キーを追加して Zip Deploy を使うだけです。
これで Web App でも Run-From-Zip が使えるようになりますが、ストレージが読み込み専用になるので App_Data に何かを書き込むようになっている場合は落ちます。特に PHP で多い wwwroot 以下にキャッシュを作るアプリの場合は無理でしょう。
元々 App Service のストレージに対して頻繁に I/O を行うのは避けた方が良いので、Redis Cache や SQL Database など外部のマネージドサービスを組み合わせれば十分実用的だとは思っています。
最後に Run-From-Zip に用意された 2 つの動作モードを紹介します。
1 つは Zip Deploy を使って Azure Files にマウントされたストレージに zip を保持するローカルモード、もう 1 つはアクセス可能な URL を指定して、実行時に zip をダウンロードしてくるリモートモードです。
リモートモードでは WEBSITE_RUN_FROM_ZIP に zip の URL を指定するだけです。App Service が再起動するたびに新しくデプロイされることになるので、ARM Template などで同時に配布する際に最適です。
実際に Azure Functions App の配布に使っていますが、CI/CD との相性が非常に良いので便利です。