【Ubuntu】Serverless FrameworkでAzure Functionsのデプロイまで

Azure Functionsを触る必要が出てきたのでデプロイ方法確認するために調べました。とりあえずUbuntuでも何とかなりそうです。

開発環境

私の開発環境です。Ubuntuです。Azureを触ることになった時にWindowsが必要かと思ったのですが、何とかなってます。

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.1 LTS"

Serverless Framework 事前準備

Ubuntu用事前準備

開発環境がUbuntuなのですが、以下のパッケージが必要でした。

sudo apt install pkg-config libsecret-1-dev

上記のパッケージ無いとnpmで serverless-azure-functions インストールする際に以下のようなエラーがでます。

gyp: Call to 'pkg-config --libs-only-l libsecret-1' returned exit status 127 while in binding.gyp. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:345:16)
gyp ERR! stack     at ChildProcess.emit (events.js:182:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:238:12)
Package libsecret-1 was not found in the pkg-config search path.
Perhaps you should add the directory containing `libsecret-1.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libsecret-1' found 
gyp: Call to 'pkg-config --libs-only-l libsecret-1' returned exit status 1 while in binding.gyp. while trying to load binding.gyp

npm

npmでserverlessのパッケージ入れておきます。

npm -g install serverless

プロジェクト作成

以下のようにプロジェクト作成して依存パッケージインストールします。-n / --name オプションはAzure上でユニークな名称である必要がります。

$ serverless create -t azure-nodejs -p test-service -n otomo-test-service
$ cd test-service
$ npm i

fseventの以下のような警告が出ますが、Macしか対応してないみたいですし、OPTIONAL DEPENDENCYだから無視します。

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

主要ファイル確認

package.json

serverless以外には以下の2つのパッケージが追加されています。

{
  "name": "otomo-test-service",
  "version": "1.0.0",
  "description": "Azure Functions sample for the Serverless framework",
  "main": "handler.js",
  "keywords": [
    "azure",
    "serverless"
  ],
  "devDependencies": {
    "serverless-azure-functions": "*"
  }
}

handler.js

エントリポイントになっているJSです。ここではメッセージログに吐いて、返すだけですね。後で動かしてみます。

'use strict';

/* eslint-disable no-param-reassign */

module.exports.hello = function (context) {
  context.log('JavaScript HTTP trigger function processed a request.');

  context.res = {
    // status: 200, /* Defaults to 200 */
    body: 'Go Serverless v1.x! Your function executed successfully!',
  };

  context.done();
};

serverless.yaml

デプロイの定義ですが、HTTPリクエストをトリガにhandler.jsのhelloを呼べる設定になっています。

# Welcome to Serverless!
#
# This file is the main config file for your service.
# It's very minimal at this point and uses default values.
# You can always add more config options for more control.
# We've included some commented out config examples here.
# Just uncomment any of them to get that config option.
#
# For full config options, check the docs:
#    docs.serverless.com
#
# Happy Coding!

service: otomo-test-service # NOTE: update this with your service name

# You can pin your service to only deploy with a specific Serverless version
# Check out our docs for more details
# frameworkVersion: "=X.X.X"

provider:
  name: azure
  location: West US

plugins:
  - serverless-azure-functions

# you can add packaging information here
#package:
#  include:
#    - include-me.js
#    - include-me-dir/**
#  exclude:
#    - exclude-me.js
#    - exclude-me-dir/**

functions:
  hello:
    handler: handler.hello
    events:
      - http: true
        x-azure-settings:
          authLevel : anonymous
      - http: true
        x-azure-settings:
          direction: out
          name: res

# The following are a few examples of other events you can configure:
#
# events:
#   - queue: YourQueueName
#     x-azure-settings:
#       connection : StorageAppSettingName
#   - blob:
#     x-azure-settings:
#       name: bindingName
#       direction: in

デプロイ実行

以下のコマンド叩くとAzureへのデプロイが始まります。

$ serverless deploy
Serverless: Building Azure Events Hooks
Serverless: Parsing Azure Functions Bindings.json...
Serverless: Building binding for function: hello event: httpTrigger
Serverless: Building binding for function: hello event: http
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Logging in to Azure
Serverless: Creating resource group: otomo-test-service-rg
Serverless: Creating function app: otomo-test-service
Serverless: Waiting for Kudu endpoint...
Serverless: Uploading function: hello
Serverless: Running Kudu command mv hello/hello-function.json hello/function.json...
Serverless: Syncing Triggers....Response statuscode: 200
Serverless: Successfully created Function App

この際にブラウザが立ち上がり認証が入ります。 以下の環境変数で事前に認証情報定義しておくこともできます。

azureSubId
azureServicePrincipalTenantId
azureServicePrincipalClientId
azureServicePrincipalPassword

デプロイが完了しました。

f:id:yomon8:20180831102335p:plain

デプロイの際にservice名がユニークでないと、以下のようなエラーが発生します。

Error --------------------------------------------------

Long running operation failed with error: "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-debug for usage details.".
 
Website with given name test-service already exists.

稼働確認

これで以下のURLでhandler.jsで定義されているhello 関数にアクセスできるはずです。。

https://{your-service-name}/api/hello

$ curl https://otomo-test-service.azurewebsites.net/api/hello
"Go Serverless v1.x! Your function executed successfully!"

参考URL

serverless.com

qiita.com