Azure Functions カスタム コンテナーで Golang を使う
Azure Functions のカスタム ハンドラーが GA です。カスタム ハンドラーを使うと Golang でもで関数アプリを実装することができます。
ですが・・・今回は、Azure Functions カスタム コンテナーです。Azure Functions Core Tools 使って function app と Dockerfile を作成し、Golang で作ったアプリを簡単に動かすことができますので試してみます。
Azure Functions Core Tools (試したのは 3.0.3160 )でプロジェクトを作成します。
func init go-func-app1 --worker-runtime custom --docker
関数と同じ名前のサブフォルダー(Hello)を作成して、構成ファイル function.json を追加します。シンプルなHTTPトリガーです。
{ "bindings": [ { "type": "httpTrigger", "direction": "in", "name": "req", "methods": [ "get" ], "authLevel": "anonymous" }, { "type": "http", "direction": "out", "name": "res" } ] }
関数を実装します。 /Hello にHTTPリクエストが来たら JSONを返すだけのコードです。
package main import ( "encoding/json" "fmt" "log" "net/http" "os" ) func main() { customHandlerPort, exists := os.LookupEnv("FUNCTIONS_CUSTOMHANDLER_PORT") if exists { fmt.Println("FUNCTIONS_CUSTOMHANDLER_PORT: " + customHandlerPort) } mux := http.NewServeMux() mux.HandleFunc("/Hello", helloHandler) fmt.Println("Go server Listening...on FUNCTIONS_CUSTOMHANDLER_PORT:", customHandlerPort) log.Fatal(http.ListenAndServe(":"+customHandlerPort, mux)) } type InvokeResponse struct { Outputs map[string]interface{} Logs []string ReturnValue interface{} } type user struct { Name string Address string } func helloHandler(w http.ResponseWriter, r *http.Request) { outputs := make(map[string]interface{}) resData := make(map[string]interface{}) resData["body"] = user{ Name: "Taka", Address: "Tokyo", } outputs["res"] = resData invokeResponse := InvokeResponse{outputs, nil, nil} responseJson, _ := json.Marshal(invokeResponse) w.Header().Set("Content-Type", "application/json") w.Write(responseJson) }
ファイル構成はこんな感じです。
host.jsonのdefaultExecutablePathにビルドで作成される main を指定します。
"defaultExecutablePath": "main",
Dockerfile に Go のビルドとコピーなどを追加して準備は終わりです。
FROM golang:latest COPY . /go/app WORKDIR /go/app RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . FROM mcr.microsoft.com/azure-functions/dotnet:3.0-appservice ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ AzureFunctionsJobHost__Logging__Console__IsEnabled=true COPY --from=0 /go/app/ /home/site/wwwroot
ビルドしてローカルで確認してみます。
docker build -t go-func-app1:latest . docker run -p 8080:80 -it go-func-app1:latest .
あとは、 Azure Container Registrなどに Push して functions に設定すれば完了です。