窓を作っては壊していた人のブログ

この謎のブログタイトルの由来を知るものはもういないだろう

【備忘録】Scala で Azure Functions やってみる(deploy編)

連載系のやつではないですが、引き続きScalaでAzure Functionsをやってみます。 ローカルに開発環境を整えてビルドを行う部分についてはこちらをご覧ください。

Scala で Azure Functions やってみる(ローカル動作編) - 窓を作っては壊していた人のブログ

前回の記事の最後あたりでdeployについて記載しました。 今回はdeploy方法について触れていこうと思います。

正直今回は備忘録レベルとリポジトリ見ろみたいな扱いです。 またGitHub Actionsを使ってみたかった、という色が非常に強いです。

github.com


自分が今までに試したAzure Functionsのデプロイ方法は3つあります。

  1. Azure Functions Core Tools(& VSCodeの拡張)
  2. curlを使ったzip deploy
  3. GitHub Actionsを使ったdeploy

それぞれ自分の感じたメリット・デメリットがあり、これがベストというものはありませんでした。 一つ一つ少しずつメモを残していきます。

Azure Functions Core Tools

メリット

  • 特にハマりどころがなく、host.json のあるディレクトリで func azure functionapp publish <Function name> を叩くだけの優しいコマンド
  • VSCodeの拡張と組み合わせるとGUIで出来るのでパット見わかりやすい

デメリット

  • ビルド環境とデプロイ環境を引き剥がすのが面倒
  • Docker上で動かすのが非常に面倒
  • 個人開発ならどうにでもなりそうだけど、チームでとなると大変そう

ローカルで動かして、そのままデプロイみたいなことが出来るのである意味完結している。 testとかもやってみたいな自動化したくなるとめんどくさそう(という印象がある)。

この辺上手くやる方法があるのであればぜひ知りたいところ…

curl

メリット

  • zipで固めて投げるだけ
  • curl と zip が使える環境ならどこでも使えそう
  • publish用のuser名とpassword(Azureのコンソール上からダウンロード出来る)を手に入れればすぐ使える
  • ローカルでもCI上でもいい感じに使えるハイブリッドな方法

デメリット

  • 機微情報ではあるので扱いに注意

とはいいつつもCIサービスはだいたいSecretEnvとかSecretValとか対応してるしちゃちゃっとTravisとかでやっちゃうのであれば普通に選択肢に入る。

https://github.com/projectkudu/kudu/wiki/Deploying-from-a-zip-file

ScalaFunctions/Makefile at master · yamachu/ScalaFunctions · GitHub

自分は上記リンクみたいにMakefileのタスクとして定義した。 Travisからは値を渡してそのタスクを叩くだけ。

GitHub Actions

メリット

  • Azure/github-actionsにAzure関係のActionsが用意されているので、それをそのまま使うだけ

デメリット

  • 手元で動かして試してみるみたいなことが出来ない(GitHub Actionsをローカルで動かしてみるって出来るんですかね…?)

Azure Functionsにデプロイするのであれば必要なのは loginアクションfunctionsアクションの2つです。

まずはloginに使用するAPP_IDやPASSWORDなどを発行するため、新規のservice principalを作ります。

コマンドライン上で

az ad sp create-for-rbac -n "ここにdeployに使用するdeployプロファイル名みたいなの" \\
    --scopes /subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP_NAME}

いい感じに値を埋めて実行すると、

{
  "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "displayName": "ここにdeployに使用するdeployプロファイル名みたいなの",
  "name": "http://ここにdeployに使用するdeployプロファイル名みたいなの",
  "password": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

こんな感じの結果が出力されます。 loginアクションで使うのは appIdpasswordtenant なのでどこかにメモっておきましょう。

service principalに関する詳しいドキュメントは以下を参照

Azure CLI で Azure サービス プリンシパルを使用する | Microsoft Docs

上記の手順で手に入れた各種値をloginアクションに追加します。 これでlogin周りは完了。

あとはfunctionsですが、これはJava以外はハマることはないでしょう。

Javaの場合は次のセクションに記載してある問題がありfunctionsアクションをそのまま使うことが出来ません。 そのため今回はオレオレスクリプトを用意し、entrypointを差し替えることを行いました。

ScalaFunctions/azure-functions-deploy.sh at master · yamachu/ScalaFunctions · GitHub

やっていることは単純で、WEBSITE_RUN_FROM_PACKAGE変数の値を1にする処理をスキップしただけです。 詳しくはリポジトリを参照してください。

これでGitHub Actionsからでもデプロイが可能になります。

ハマった場所

現状対象のAzure Functionsの展開方法がパッケージからになっている状態(WEBSITE_RUN_FROM_PACKAGE=1の状態)だと展開が正常に行われないという現象が起こっているように見られます。

Deploying Java Jar to Web App completes successfully but the Web App does not start - Developer Community

Unable to Deploy · Issue #181 · Azure/azure-functions-java-worker · GitHub

WEBSITE_RUN_FROM_PACKAGE=0にしたら動いたみたいな解決方法になっているため、curlAzureのGitHub Actionsを使ってのzipdeployでハマる可能性があります。(AzureのGitHub ActionsはここWEBSITE_RUN_FROM_PACKAGE=1にしているためそのまま使うと……)

おそらくこの辺りのIssueに関連しているのかなと思いますが、深くはまだ探っていない状態です。

完全にメモ書きになってしまった。