Serverless Frameworkを使ってAWSでお手軽kintone REST APIを実行してみよう

著者名: 門屋 亮 (External link) クローバ株式会社 (External link)

目次

はじめに

こんにちは。クローバの門屋です。
AWS Lambdaの登場以来、サーバーレスなアーキテクチャを使ったシステムの構築が注目されています。
kintoneでサーバーレスの恩恵を受けやすいのはやはり 他のサービスとの連携 ではないでしょうか。
LambdaとAPI Gatewayを使えば、常時稼働するサーバーいらずでkintoneとの連携サービスを作ることができます。
ただやってみるとわかるのですが、複数のLambda関数やAPIを開発する場合に都度、LambdaやAPI Gatewayの設定を手作業で行うのはわりと面倒くさいものです。
Serverless Frameworkとserverless-kintoneプラグインを使えば、煩わしい設定を極力行わずにサーバーレスなシステムを構築できます。

Serverless Frameworkとは?

Serverless Frameworkは今非常に注目されているサーバーレスなアーキテクチャを簡単に作成できるオープンソースのフレームワークです。
AWS Lambdaだけでなく、Azure Functions、Google CloudFunctionsなどに対応しており、2017年3月現在でバージョン1.8が提供されています。

serverless-kintoneとは?

serverless-kintoneとは、Serverless Frameworkでkintoneを扱うためのプラグインです。
設定ファイルにkintoneの設定を記述するだけで、簡単にkintoneを操作できます。

下準備

必要なもの

  • kintoneアカウント
  • AWSアカウント
  • AWSコマンドラインインターフェース
  • node.jsおよびnpm

AWS CLIのセットアップ

AWSコマンドラインインターフェースは事前にaws configureコマンドでセットアップを行ってください。
詳しくは AWS CLIのインストールと設定 (External link) を参照してください。

kintoneアプリの作成とAPIトークンの取得

詳しい方法は省略します。
APIトークンの取得については 過去の記事 を参考にしてください。

Serverless Frameworkのインストール

Serverless Frameworkはnpmで提供されており、以下のコマンドでインストールできます。
gオプションをつけてグローバル環境でインストールします。

1
npm install serverless -g

アプリケーションの初期化

新しくディレクトリを作って、Serverless Frameworkの初期化コマンドを実行します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
mkdir sls-kintone
cd sls-kintone
serverless create --template aws-nodejs

Serverless: Generating boilerplate...
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.5.1
 -------'
Serverless: Successfully generated boilerplate for template: "aws-nodejs"
Serverless: NOTE: Please update the "service" property in serverless.yml with your service name

作成されるファイルについて説明します。

  • handler.js: Lambda関数を実装するJSファイル
  • serverless.yml: フレームワークの設定ファイル

package.jsonの初期化

なにはともあれnpm initを実行してpackage.jsonを初期化します。
いろいろ聞かれますがとりあえずすべてデフォルトで大丈夫です。

1
npm init

serverless-kintoneプラグインのインストール

現時点ではまだserverless-kintoneはnpmのレジストリに登録されていないため、直接GitHubからインストールします。

1
npm install https://github.com/kintone/serverless-kintone --save

APIトークンの暗号化

serverless-kintoneでは、APIトークンとパスワード認証に対応しており、APIトークンとパスワードはどちらも暗号化してAWSにアップロードできます。
運用環境では必ず暗号化を行うようにしてください。
事前にAWSにてKMSのキーを作成しておく必要があります。
とりあえず試すだけなら、本章は省略してもかまいません。

KMSキーの作成

Creating keys (External link) を参考にしてキーを作成してください。
あとで作成されるLambda関数の実行アカウントに、このキーのkms:Decrypt権限を与える必要があります(Lambda関数の作成後に設定します)。

暗号化

コマンドラインで以下のコマンドを実行します(AWSコマンドラインインターフェースが必要です)。
表示される暗号化されたキー(CiphertextBlobの値)をメモしておいてください。

1
2
3
4
5
6
aws kms encrypt --key-id alias/{KMSキーのエイリアス} --region ap-northeast-1 --plaintext {APIトークン}

{
    "KeyId": "arn:aws:kms:ap-northeast-1:xxxxxxx:key/xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
    "CiphertextBlob": "{your key}"
}

これで下準備ができました!

アプリケーションの開発

serverless.ymlの編集

serverless.ymlを以下のように編集します。
kintoneの情報はご利用のものに置き換えてください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
service: kintone-sample # 任意のアプリケーション名を設定します。

provider:
  name: aws
  runtime: nodejs8.10
  region: ap-northeast-1

functions:
  hello:
    handler: handler.hello # helloという名前のLambda関数を実装します。
    events:
      - http:
          path: hello # API Gatewayのパス
          method: get # API Gatewayのメソッド

plugins:
  - serverless-kintone # serverless-kintoneプラグインを使用します。

custom:
  kintone:
    - name: test_app # アプリ名(kintoneのアプリ名と一致する必要はありません)
      domain: example # ドメイン
      api_token: {your key} # 暗号化されたAPIトークン
      encrypted: true # 暗号化を行う

詳しい設定方法については、 Serverlessのドキュメント (External link) を参照してください。

暗号化を行わない場合は、encryptedの行を削除して、api_tokenに暗号化されていない値を設定してください。

handler.jsの編集

handler.jsを以下のように編集します。
今回は単純に、kintoneの特定のアプリからレコード情報を返すだけのAPIを作成してみることにします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
 * Serverless Framework sample
 * Copyright (c) 2019 Cybozu
 *
 * Licensed under the MIT License
 * https://opensource.org/license/mit/
 */

'use strict';

const Kintone = require('kintone');
const app = new Kintone('test_app');

module.exports.hello = (event, context, callback) => {
  const params = {
    app: 1 // your APP ID
  };
  app.get('/k/v1/records', params).then((res) => {
    const response = {
      statusCode: 200,
      body: JSON.stringify({
        records: res.records
      }),
    };

    callback(null, response);
  });
};

複数のLambda関数の作成も可能です。
アプリケーションが大きくなるとフォルダーを作成してファイルを整理することもあると思います。
このとき、アプリケーション直下に「kintone」という名前のフォルダーを作成するとserverless-kintoneに上書きされてしまうので注意してください。

デプロイ

以下のコマンドで、アプリケーションをAWSにデプロイします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
serverless deploy

Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading service .zip file to S3 (1.93 MB)...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
...............................
Serverless: Stack update finished...
Service Information
service: kintone-sample
stage: dev
region: ap-northeast-1
api keys:
  None
endpoints:
  GET - https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello
functions:
  kintone-sample-dev-hello: arn:aws:lambda:ap-northeast-1:xxxxxx:function:kintone-sample-dev-hello

デプロイには少し時間がかかります。
Lambda関数を修正した場合などは、deploy functionコマンドを使うと関数だけの更新もできます。

APIの実行

デプロイ時に表示されたURLへcurlコマンドやブラウザーでアクセスしてみます。
APIトークンを暗号化した場合は、トークンを復号できないためにエラーが発生します。
Serverless Frameworkによって作成されたIAM Roleに、復号するためのkms:Decrypt権限を付与すると実行できます。
詳しくは Key policies in AWS KMS (External link) の、「キーユーザーにCMKの使用を許可する」を参照してください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
curl https://xxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello | jq .

{
  "records": [
    {
      "Updated_datetime": {
        "type": "UPDATED_TIME",
        "value": "2017-03-11T08:13:00Z"
      },
      "Created_datetime": {
        "type": "CREATED_TIME",
        "value": "2017-03-11T08:13:00Z"
      },
      "file": {
        "type": "FILE",
        "value": []
      },
      "Record_number": {
        "type": "RECORD_NUMBER",
        "value": "17"
      },
      "multi_text": {
        "type": "MULTI_LINE_TEXT",
        "value": "aaabbb"
      },
      "checkbox": {
        "type": "CHECK_BOX",
        "value": []
      },
      "Created_by": {
        "type": "CREATOR",
        "value": {
          "code": "Administrator",
          "name": "Administrator"
        }
      },
      "text": {
        "type": "SINGLE_LINE_TEXT",
        "value": "test1"
      },
      "$revision": {
        "type": "__REVISION__",
        "value": "1"
      },
      "Updated_by": {
        "type": "MODIFIER",
        "value": {
          "code": "Administrator",
          "name": "Administrator"
        }
      },
      "$id": {
        "type": "__ID__",
        "value": "17"
      }
    },

kintoneからデータが取得できています!

おわりに

いかがだったでしょうか。
暗号化のところが少し複雑でしたが、キーの作成はじめに一度行うだけでよく、自前で暗号化のしくみを作成することと比べると、とても簡単にセキュアなサーバーレスアプリケーションを構築できます。
LambdaやAPI Gateway、DynamoDB等の設定が設定ファイルで管理できるため、ちょっとAPIを作ってみたいというケースから大規模な開発まで対応できます。
Serverless Frameworkは開発のスピードが早いため、最新情報をキャッチアップしていく必要がありますが、使いこなせば強力なツールになることは間違いありません。
ぜひ試してみてください。

注意事項

ソースコードの変更および再配布、商用利用等はライセンスにしたがってご利用可能です。

information

このTipsは、2019年8月版kintoneで動作を確認しています。