【Azure Functions】ローカル開発でもカスタムコンテナーを使いたい!
Azure Functionsを利用するアプリ開発(≠Azure Functionsの開発)において、どのようにローカル開発を行うかというのは大きな課題です。
一番ベタなのは azure-functions-core-tools
を使用しての開発かなと思いますが、Functions自体はコンテナ化しておきたいと考えると、ローカル開発とデプロイされるものが異なってしまうのが難点かなと個人的には思います。
というわけで、今回はローカル環境で本番と同じコンテナイメージを使って開発してしまおうという内容になります。
はじめに: カスタムコンテナーとは?
そもそも、Azure Functionsにはソースコードをコンテナに配置して、そのイメージをデプロイするというオプションがあります。
カスタム イメージを使用して Linux 上で Azure Functions を作成する | Microsoft Learn
これをドキュメントでは「カスタムコンテナー」として扱っているんですが、クラウドにデプロイして使う方法しかドキュメントには載っていません。ローカルでも使えたらきっと便利ですよね。
カスタムコンテナーで内部的に使用されているのは azure-functions-host
上記の手順に従ってカスタムコンテナーを作って動かしてみると、どうも内部的に使用されているのは azure-functions-host
というものらしいです。詳細は以下のリポジトリを参照。
GitHub - Azure/azure-functions-host: The host/runtime that powers Azure Functions
これはどうやらAzure Functionsで使用されているランタイムのようで、これ公開してるのすごいなと思いつつ、仕様がオープンになっているのでありがたく使わせていただきましょう。
カスタムコンテナーをローカル開発で使用する手順
では、ここからはAzure Functionsで使用するカスタムコンテナーをローカル開発で使用するにあたって必要な手順を書いていきたいと思います。
カスタムコンテナーを作る
まずはドキュメントに従ってカスタムコンテナーを作ります。
mcr.microsoft.com/azure-functions/python
などをベースに、requirementsをインストールしてソースコードを /home/site/wwwroot
に配置するという感じになるかなと思います。(pythonのばあい)
起動用のdocker-composeを書く
次に、起動用にdocker-composeを書いていきます。
version: '3.7' services: functions: build: . environment: AzureWebJobsStorage: DefaultEndpointsProtocol=https;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://azurite:10000/devstoreaccount1;QueueEndpoint=http://azurite:10001/devstoreaccount1; AZURE_FUNCTIONS_ENVIRONMENT: Development ports: - 80:80 azurite: image: mcr.microsoft.com/azure-storage/azurite hostname: azurite restart: always ports: - 10000 - 10001 - 10002
ローカルでキューストレージのトリガを使ったりするために Azurite というストレージアカウントのエミュレータを同時に動かすようにしています。(なくても動くかも。)
(Optional)ローカル開発時の認証を消す
azure-functions-core-toolsでは、実行時にauthLevelがanonymous
になるという仕様があるんですが、このカスタムコンテナーだとそれがありません(本番環境にも同じものがデプロイされるので当然)。なので、本番はauthLevelでfunction
で使うことを想定している場合にカスタムコンテナーではローカル開発では使用できないという問題が発生してしまいます。
というわけで、私は起動時の実行コマンドで以下のようにsedでauthLevelをanonymous
に変更して起動するようにしてみました。
command: >- bash -c ' sed -i -e "s/\"authLevel\":.*/\"authLevel\": \"anonymous\",/" /home/site/wwwroot/hogefunc/function.json && /azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost '
実行する
作ったdocker-compose.ymlファイルを通常通り起動すればOKです。
docker-compose up
終わりに
以上、ローカル開発でAzure Functionsのカスタムコンテナーを使用するという話でした。
ユースケースとしては、
「Azure Functionsに直接乗っかるものを開発するのには azure-functions-core-tools
を使用して、ある程度固まったらカスタムコンテナー化して今度はそのFunctionsを利用する側のアプリを書く」
そんな感じでうまく使い分けられると良いんじゃないかと思いました。
今回作ったdocker-compose.ymlをベースにdevcontainersで使用したりするのもGOODですね。