🍏

AzureでWebアプリを作る時、サーバレスを諦めてコンテナにした話

2021/11/30に公開

タイトルの通りです。
私のAzure力がなかったため、当初は所謂ServerlessでWEBアプリを作ろうと考えていたアプリを最終的にContainerで構築した話を書きます。

そもそもサーバレスってなに?

wikipediaによると、、

サーバーレス・コンピューティング(Serverless computing)とは、クラウド・プロバイダーがアプリケーションに必要なマシン・リソースの割り当てを動的に管理し、事前に購入されたことに基づく請求ではなく、各アプリケーション要求を満たすために使用される個々のリソース量に基づいた請求を行うようなクラウド・コンピューティングの実行モデルである。

ざっくり言ってしまうと、AWS LambdaなどのFaasサービスを使って、サーバーをほぼ意識することなくアプリを作ってしまうことですね。

アプリの構成

当初構想

AWS Lambdaに相当するAzureのサービスはFunctionsですので、
こんな感じでAzure Functionsを中心としたサーバレス構成にする予定でした。

  1. Frontend : Typescript+React
    • Azure Static Web Apps
  2. Backend(API) : Python
    • Azure Functions
  3. Backend(イベント処理) : Python
    • Azure Functions
    • ファイルがアップロードされたのをトリガーに処理を実行する
  4. Database
    • Cosmos DB (serverless)

できたもの

結局、こんな感じでContainerで構築しました。

  1. Frontend : Typescript+React
    • Azure Web Apps (Container)
  2. Backend(API) : Python
    • Azure Web Apps (Container)
  3. Backend(イベント処理) : Python
    • Azure Functions (Container)
  4. Database
    • Cosmos DB (serverless)

なぜ、Containerにしたのか?

Backend(API)編

まず、APIはAzure Functionsを使ってサーバレスで作ろうとしていたのですが、諦めました。
そもそもですが、Azure Functionsは、AWS Lambdaに慣れてる人とって、はっきり言って辛いです。
どう辛いかは、sakojunさんがいい感じの記事を書いているので、勝手に貼ります。
https://zenn.dev/sakojun/articles/20210529-azure-functions

その上で、Azure Functionsを諦めた理由を書きますと下記のようになります。

  • Azure Functionsは従量課金プランでないとServerlessと呼べるものではない(常時課金される)
    • 従量課金プランはセキュリティ機能が制限されるし起動が遅すぎるしでAPIとして使うのが厳しい
    • 常時課金されるならAPIにFunctionsを使うメリットが少ない
  • APIの管理にAzure API Managementが欲しくなるが、金額が高すぎるので使いたくない
    • Amazon API Gatewayと同じと考えてはいけない
  • Serverless Frameworkを使おうとしたが、Azure Functionsでの使用事例が世の中に少なすぎて調べるのが面倒くさくて嫌になった
  • PythonでAPIを書くならFastAPIを使いたかった

結局の所、Azure FunctionsでAPIをまともに作ろうとすると常時課金のプランが必要になり、それだとコストメリットが無いので、Containerを作ってAzure Web Appsにdeployしたほうが使い勝手がいいと言う感じです。

Backend(イベント処理)編

次にサーバレスを諦めたのは、バックエンドのAzure Functionsです。
この処理は、ファイルがアップロードされたのをトリガー起動する処理なので、一番サーバレスに向いている処理です。しかし、今回のアプリでは問題がありました。この関数で必要となる画像処理ライブラリが、従量課金プランでは動きませんでした。これはAzure固有の問題と言うわけではなくAWSのLambdaでも苦労する部分になりますが、いずれにしても動かないのでサーバレスは諦めました。
幸いなことにAzure Functionsはサーバレス(従量課金プラン)さえ諦めてしまえば、Containerに対応していますので、Containerに必要なライブラリをインストールしてAzure Functionsにデプロイすることで動作させることができました。
(Azure Functions使ってるならserverlessでは?という意見もあると思いますが、常時課金される時点でserverlessとは呼べないよね?と個人的には思っています。)

ちなみにAzure FunctionsのContainer対応は、AWS LambdaのContainer対応よりも先に実装されていて、かつてはAzureがAWSより優れている点だと認識していたのですが、今となってはLambdaもContainerに対応していますね。

Frontend編

最後に、FrontendのAzure Static Web Appsをやめて、Azure Web AppsにContainerでdeployに変えました。これに関しては、下記が理由です。

  • Azure Static Web Appsを業務アプリに使うには、認証系の機能がAzure Web Appsより使いづらい
    • 逆に一般公開するアプリであれば、Azure Static Web Appsの方が使いやすいです
    • 何故、認証認可の仕様が違うのか謎です。両方のいいとこ取りして展開して欲しいです
  • 開発開始時には、Azure Static Web Appsは当時まだpreviewだったので不安だった
    • 今ではpreview取れてます
    • Azureはpreviewが多いので、サービス選定の判断するときにけっこう困ります
  • 他がContainerになったので、統一してしまおうと思った

Frontendは認証周りさえAzure Web Appsと同等に使えれば、今からでも乗り換えたいです。バージョンアップ頼む。特にCI/CDに関しては、Azure Static Web Appsを使うことでAWSのAmplifyみたいに簡単に構築できるのでかなり楽になります。

Databaseはserverless

Databaseだけ、serverlessで残っています。
理由としては、特に困ってないし何より安いからです。
現時点でアプリの規模がそれほど大きくなく、性能もそれほど求められていないからなんとかなっています。今後アプリの規模を拡大するときには再検討が必要になると思っています。

ですが、それにしてもこのCosmosDBのserverlessは本当に費用が安いです。このシステムのインフラ費用の中でDBの割合はわずか5%程度です。
AWSとAzureを比べた時にクラウドサービス全体としてはAWSのほうが使いやすいというのが本音ですが、DBに関しては、Azureの方が費用も含めて使いやすい点が多いと個人的には思っています。(DBそんなに詳しくないので、あまり偉そうなことは言えないですが)

おまけ - Azure Container Appという新サービスが出たらしい

いつの間にか「Azure Container Apps」という、新しいContainerのサービスが使えるようになっていました。Ignite 2021で発表されたようです。
https://azure.microsoft.com/ja-jp/services/container-apps/

AWS App Runnerみたいなものでしょうかね。機会があったらそのうち試してみます。

最後に

そもそもなんですけど、Azureサーバーレスのページを見るとAKSやK8s使ったりしているので、Container使うのが前提っぽいんですよね。
(2022/06/10追記:いつの間にかページが更新されてContainer色が薄くなっていて、何を言いたいのかが分かりにくくなってますね。以前のページをキャプチャしておけばよかった。。。)
https://azure.microsoft.com/ja-jp/solutions/serverless/

ですので、AzureにとってサーバレスとはFaasではなくCaasなんだと思います。
AWSのLambdaと同じ感覚でAzure Functionsを使うことがそもそもの間違いで、Azureの思想に従ってアプリ開発をするのが無難なんだと思います。

AWSとAzureの比較表みたいなのはググれば見つかるんですけど、思想の違いは実際に触ってみないとなかなか分からないのが辛いところです。

NCDCエンジニアブログ

Discussion