かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

何処でも動くサーバーレスプラットフォーム Azure Functions

この記事は Serverless2 Advent Calendar 2018 の 2 日目の記事です。

qiita.com

本文

最近 Docker でパッケージングしたらどこでも動くが実現してるようなものなので、実質 Docker でパッケージング出来たら run anywhere な感じということです!

そして、Azure Functions は Docker をサポートしています。(2018/12/02 時点ではプレビュー) ということでやってみましょう。私は Windows 10 に Docker を入れて試しました。

基本的には以下のドキュメントに沿ってやります。

docs.microsoft.com

ではやってみましょう。 といっても難しいことは特になくて、func コマンドでプロジェクトを作るときに --docker オプションをつけてやります。任意のフォルダで以下のコマンドをうってみましょう。

func init --docker

そうすると dotnet, node, python から選択できるので今回は node で行ってみようと思います。実行結果は以下のような感じのログになります。Dockerfile まで出来ちゃってますね!

Select a worker runtime: node
Writing .gitignore
Writing host.json
Writing local.settings.json
Writing C:\Users\kaota\.vscode\extensions.json
Writing Dockerfile

早速 Visual Studio Code で開いてみましょう。

FROM mcr.microsoft.com/azure-functions/node:2.0

ENV AzureWebJobsScriptRoot=/home/site/wwwroot
COPY . /home/site/wwwroot

思ったよりシンプル。確かに node の場合はビルドとかいりませんしね。因みに dotnet を選択すると以下のような Dockerfile が生成されます。

FROM microsoft/dotnet:2.1-sdk AS installer-env

COPY . /src/dotnet-function-app
RUN cd /src/dotnet-function-app && \
    mkdir -p /home/site/wwwroot && \
    dotnet publish *.csproj --output /home/site/wwwroot

FROM mcr.microsoft.com/azure-functions/dotnet:2.0
ENV AzureWebJobsScriptRoot=/home/site/wwwroot

COPY --from=installer-env ["/home/site/wwwroot", "/home/site/wwwroot"]

こちらも十分シンプルに見えます!公式がおぜん立てしてくれたベースイメージがあるのは強いですね。

このままだと空の関数になってしまうので func new をうちこんで HttpTrigger の関数を 1 つ作ります。 関数名は Echo を指定しました。そして生成されたファイルをちょっと変えて以下のようにします。

function.json

{
  "disabled": false,
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

index.js

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    context.res = {
        status: 200,
        body: `You said '${req.query.message}'`
    };
};

まずは、func start でローカルで実行してみます。先ほど作成した Echo 関数がちゃんと認識されてることがわかります。

Http Functions:

        Echo: [GET] http://localhost:7071/api/Echo

curl コマンドで叩いてみるとこんな感じ。ばっちりですね。

> curl http://localhost:7071/api/Echo?message=Hello
You said 'Hello'

そして docker build -t okazuki/serverless2018:v1 と打ち込んで docker でパッケージングします。

そして、docker run -p 8080:80 okazuki/serverless2018:v1 と打ち込んで実行しましょう。docker ps をして動いてるのを確認!

CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS       PORTS                  NAMES
2ce0a0ec453c        okazuki/serverless2018:v1   "/bin/sh -c /azure-f…"   About an hour ago   Up 9 seconds        0.0.0.0:8080->80/tcp   gallant_hugle

先ほどと同じように curl コマンドで docker run で指定した 8080 ポートに対して関数のエンドポイントを叩いてみます。

>curl http://localhost:8080/api/Echo?message=Hello
You said 'Hello'

ばっちりですね。docker kill で止めておきましょう。

ここまで出来たら後はお好みの環境で動かすだけですね。 まぁ Azure Functions の機能自体が Azure Storage に依存してたりするので(Durable Functions とか) そういうのを使おうとすると結局 Azure のサービスが必要でレイテンシを考えると Azure でホストするしかないのかぁ…となりそうな気もします。

でも、Azure Functions はバインディング(トリガーやアウトプットやインプット)は自作出来るようになってるので例えば AWS 系サービスのトリガーとかを作ったらいい感じに AWS 上で Azure Functions を動かすことも出来るかもしれませんね。

IoT デバイスで Azure Functions を動かすのも Docker を使ってるので、Azure Functions の Docker 対応は要注目な気がします。

まとめ

Azure Functions は Docker イメージ作れるのでどこでも動く。

Azure Functions に興味がある人は、無料で教育用の Azure 環境をクレカ不要で使いながらテキストを進めることが出来る Microsoft Learn というサイトがあるので、そこから試してみてください。因みに無料枠でも Azure Functions 出来ます。

docs.microsoft.com

azure.microsoft.com

誰か

Azure Functions on AWS とかしてくれないかな?