同僚から、Azure のサーバーレスに対して一つのリクエストをもらった。彼は、python で書きたいらしい。サーバーレスのもっとも良いところは、サーバーをある意味気にしなくていいところだが、使ったぶんだけ課金というパートを除けば、常にクラスタをデプロイしたままでのサーバーレス環境も生産性という意味では悪くないかもしれない。

自分がサーバーレスの世界に求めるのは、何と言っても簡単さだ。だから、セットアップもできるだけしたくない。今回は、たまたまハッカソンで触った OpenFaaS という Swarm / k8s にデプロイしたら動くシンプルなものを作って、彼のデマンドに答えてみたい。OpenFaaS は、ストレージや、キューのトリガーすらない、httpだけの非常にシンプルなものだ。
基礎的なアイデア
基礎的なアイデアはとしてもシンプルだ。彼からのお題は、ブロブにアップロードした画像解析をpython でサクッとしたいとのことだ。ライブラリが充実しているから python がいいらしい。ところが、Azure Functions は今の所、Windows ベースなので、Python や Ruby が使えたところで、ネィティブエクステンション系のライブラリは相当辛いだろう。
だから、こんな感じはどうだろう?
Blob -> Logic Apps -> OpenFaaS -> Blob
単純にいうと、ブロブに何かアップロードされたら、Logic Apps が拾って、httpのリクエストを、Open FaaS に投げる。Open FaaS は同期もしくは、非同期でそのリクエストを受け取って、リスクエストに格納されたファイル名にアクセスして、取得して分析するという感じ。このクソシンプルな作戦だと、OpenFaaSじゃなくても他のでも使える。ちなみに、Azure Container Instance を使わなかったのは、今の所オースケストレーターがないから。また、高負荷にも多分耐えられないから(スケールしないので)今後楽しみね。
OpenFaaS でファンクションを作る
まずは、OpenFaaS 側でファンクションを作ろう。必要なものは、2つだけ。シンプルなエコーもどきを、実装しよう。JSON の方がいいだろうから、JSON でエコーするようにする。OpenFaaS のセットアップは、私のブログポストを参考にしてほしい。
必要なものは、2つだけ。 handler.py と、storage.yaml 。ファンクションの名前をつけたディレクトリを作って、そこに、handler.py を置くだけ。
├── storage
│ └── handler.py
├── storage.yaml
handler.py
import json
def handle(req):
print('{ "recieve" : ' + req + "}")
storage.yaml (名前はなんでも良い)
provider:
name: faas
gateway: http://13.93.212.187:8080
functions:
storage-trigger:
lang: python
handler: ./storage/
image: tsuyoshiushio/storage-trigger
どちらも一回書いてしまえばクソ簡単。デプロイしよう。
faas-cli -action build -f ./storage.yaml
faas-cli -action push -f ./storage.yaml
faas-cli -action deploy -f ./storage.yaml
準備おっけー。ちなみに、OpenFaaS は内部で Docker を使っているので、ネイティブエクステンション問題は問題ない。Windows Container にも対応しているらしい。(それだったら、Azure Function使うけどw)

Logic Apps を設定する
Logic Apps は、Azure のサーバーレスのオファーの一つで、コーディングレスで、いろんなサービスをつなぐことができる。Azure に限らない。いろんなイベントを拾うことができる。Blob にアップされたらとか、VM ができたら、Event Grid という仕組みもできたので、ほぼ全てのイベントを拾うことができる。
イベントきっかけで、いろんなサービスを連携させることができる。今回は、ブロブのイベントを拾って、OpenFaaS で作ったファンクションに連携させる。ちなみに、事前に、Storage Account は作成しておいた。
ちなみに Logic Apps の Web action でハマったところは、最初、このアプリがBad Request で帰ってきたこと。正しい Json ではないとのこと。原因は、Logic Apps 側の設定ではなく、Function が返してきたレスポンスが、正しい Json ではないから。手元を散々見直してハマったが、実は、向こう側の問題だったということ。

これを、保存して実行させておいて、ブロブに何かの画像をアップさせる
そしたら、自動的に、Logic Apps がイベントを拾って、ファイル名を、ファンクションにポストする

あとは、自分で、Azure SDK を使ってキューを取りに行かないと行けないけど、かなり楽チンじゃないかなぁー。
終わりに
次回は、ここから発展させてみて、色々繋げてみる。また、Function を作ったら、できれば、Logic Apps を書くのを自動化できないかなとかふと思ってみたり。