最近、Azure Functionsのお勉強をチマチマと始めました。色々と分からないことが多かったのでお勉強メモをまとめて記します。
どこまで続くかわからないお勉強メモ。今日は4回目です。今回はRubyです。過去のものは以下を参照。
- Azure Functionsのお勉強メモ(3)Spring Cloud FunctionでTimer Triggerを実装する - miyohide's blog
- Azure Functionsのお勉強メモ(1)TypeScriptでチュートリアルを実施する - miyohide's blog
- Azure Functionsのお勉強メモ(2)Spring Cloud FunctionでHTTP Triggerを実装する - miyohide's blog
Azure Functions上のアプリをRubyで作る
Azure Functionsでサポートしている言語は2021年3月末現在、以下のものに限られています。
- C#
- JavaScript
- F#
- Java
- PowerShell
- Python
- TypeScript
詳細は以下のドキュメントに書かれています。
自分が得意なRubyが入っていない...。ただ、Dockerを使えば動かせるというようなことが以下のドキュメントに書かれています(ドキュメントはR言語の例)。
ここでは、Rubyで動くように実装してみることにします。
プロジェクトの作成と設定
とは言っても、ほとんど上のドキュメントに書かれていることを実行するだけです。
func init
コマンドでプロジェクトを作成します。
func init プロジェクト名 --worker-runtime custom --docker
これでプロジェクト名のディレクトリが作成されるので、そのディレクトリに移動後、func new
で関数の設定ファイルであるfunction.json
を作成します。
cd プロジェクト名 func new --name Hello --template "HTTP trigger"
これでHello
ディレクトリにfunction.json
が生成されます。
function.json
を開き、"authLevel"
の値を"anonymous"
に変えておきます。これはAPIアクセスの時にAPIキーを求めるかどうかの設定です。詳細は以下のドッキュメントにあるauthLevel
の項を参照してください。
最後にhost.json
の設定をします。"customHandler"
の部分を以下のように修正します。
"customHandler": { "description": { "defaultExecutablePath": "ruby", "workingDirectory": "", "arguments": ["app.rb"] }, "enableForwardingHttpRequest": true }
私は"enableForwardingHttpRequest"
の記述をすっかり見落としており、うまく動かなくてかなり悩みました。この項目の意味は以下のドキュメントを参照すると良いと思います。
アプリの実装
アプリはSinatraを使って実装します。リクエストがあったらテキストを返すだけの簡単なものでしたらRailsよりもSinatraのほうが楽でしょう。実装もこれだけです。
require 'sinatra/base' class MyApp < Sinatra::Base configure do set :environment, :production set :port, ENV['FUNCTIONS_CUSTOMHANDLER_PORT'] end get '/api/Hello' do 'Hello Ruby World' end run! if app_file === $0 end
:port
でリクエストを受け付けるポートを環境変数FUNCTIONS_CUSTOMHANDLER_PORT
で指定する必要があるのが注意点といえば注意点かと思います。
Gemfileの準備
Gemfile
にて利用するライブラリを記述します。単純なSinatraの機能しか使わないので、以下の記述になります。
source "https://rubygems.org" gem 'sinatra', '~> 2.1.0'
Dockerfileの準備
ドキュメントによればAzure Functionsの環境として作成するにはベースイメージとしてmcr.microsoft.com/azure-functions/dotnet:3.0-appservice
を使う必要があるとのこと。
イメージの実装はこのリポジトリのようです。
Rubyを動かすためにはいろいろな方法があるかと思いますが、手っ取り早くまずはapt-get install ruby
でインストールしてみます。ここでインストールされるRubyは2.5系だったので、gem i bunder
も実行しています。
FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ AzureFunctionsJobHost__Logging__Console__IsEnabled=true RUN apt update && \ apt install -y \ ruby \ && rm -rf /var/lib/apt/lists/* WORKDIR /home/site/wwwroot RUN gem install bundler --no-doc COPY Gemfile /home/site/wwwroot/ RUN bundler install COPY . /home/site/wwwroot/
実行
後は、docker build
でDockerイメージを作成し、docker run
で動かした後にhttp://localhost:8080/api/Hello
にアクセスすると、Hello Ruby World
という文字列がブラウザ上に表示されます。
コンソールログには以下のような文字列が出力されていました。Sinatraが出力しているログがfail
になっているのがちょっと気になりますが、とりあえず動いているようです。
Host lock lease acquired by instance ID '000000000000000000000000714A9D2E'. info: Function.Hello[1] Executing 'Functions.Hello' (Reason='This function was programmatically called via the host APIs.', Id=66a1a41b-2d0c-4277-90d3-a5ef3990be81) fail: Host.Function.Console[0] 127.0.0.1 - - [01/Apr/2021:11:40:05 +0000] "GET /api/Hello HTTP/1.1" 200 16 0.0004 fail: Host.Function.Console[0] 127.0.0.1 - - [01/Apr/2021:11:40:05 UTC] "GET /api/Hello HTTP/1.1" 200 16 fail: Host.Function.Console[0] - -> /api/Hello info: Function.Hello[2] Executed 'Functions.Hello' (Succeeded, Id=66a1a41b-2d0c-4277-90d3-a5ef3990be81, Duration=66ms)
Azure上で動かす
Azure上で動かしてみます。Dockerイメージをdocker push
でDocker Hubに格納したのち、Azure上で動かします。Azure Portal上で「関数アプリ」に必要な項目を入力し、作成。作成後、「デプロイセンター」から「完全なイメージの名前とタグ」を指定して保存すればAzure上で動かすことができました。
ソース
現時点でのソースです。