GAE環境でNode-REDを使う

こんにちは。
この記事は「[Google Cloud Platform Advent Calendar 2020](https://qiita.com/advent-calendar/2020/gcp)」10日目の記事です。

# はじめに
Node-REDが好きでプライベートでも仕事でもよく使ってますが、GCP環境と親和性が高く、GAEで動かせる情報がなかなかなかったため、GAE用のスターターコード`Node-RED-Starter-GoogleAppEngine`を作ってみました。今回はそのスターターコードをGAEにデプロイ/動作確認するまでの流れを纏めてみました。
https://gitlab.com/ktsz/node-red-starter-googleappengine.git

# 構成
今回は、ローカルで開発したNode-REDを、GitlabのCI/CDを利用しGAEにデプロイして使う、以下のような構成で構築します。
![スクリーンショット 2020-12-10 21.26.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142110/b2ea3e9d-be3f-44cb-7c7c-421760be64fe.png)


# 環境準備
## Google Cloud Platform の準備
Node-RED-Starter-GoogleAppEngineは、実行環境としてGCPのApp Engine FlexibleもしくはStandard環境を利用します。今回はFlexibleで構築します。GAEの詳細については、以下サイトをご確認ください。
https://cloud.google.com/appengine?hl=ja
（GAE Standardでも動作可能ですが、GAE Standardの制約はそのまま受けますので、Node-REDの利用上は例えばDebugタブにログを出力することができないなど、制約があります。）

### API有効化
以下5つのAPIが必要となります。左上のハンバーガーメニュー >「APIとサービス」>「ダッシュボード」>「APIとサービスを有効化」を開き、有効化ください。

- Compute Engine API
- App Engine Admin API
- Google App Engine Flexible Environment
- Cloud Build API
- Cloud Deployment Manager V2 API

### サービスアカウント作成
デプロイ時に使用するサービスアカウントと、Node-RED storageModuleで使用するサービスアカウントを作成します。左上のハンバーガーメニュー >「IDとセキュリティ」>「ID」>「サービスアカウント」>「サービスアカウントを作成」より作成ください。

- gitlab-ci デプロイ用 必要権限
  - App Engine サービス管理者
  - App Engine デプロイ担当者
  - Cloud Build 編集者
  - ストレージオブジェクト 管理者
  - サービス アカウント ユーザー
- Node-RED storageModule用 必要権限
  - ストレージ 管理者

作成後、JSON形式でキーを作成し、ダウンロードしてください。（安全に保管してください。）

### GAE有効化
GAEを有効化します。以下設定値を参考に有効化ください。

| 項目 | 値 |
| ------ | ------ |
| Region | 任意（ここでは asia-northeast1（東京）を選択） |
| Language | Node.js |
| Environment | フレキシブル |


## Gitlab の準備
GAE用のNode-REDスターターコードの準備と、GAEに自動デプロイするためのCI/CDの設定を行います。  

### スターターコード準備
スターターコードを自分のGitプロジェクトへインポートします。以下に「Node-RED-Starter-GoogleAppEngine」スターターコードがありますので、こちらをインポートください。
https://gitlab.com/ktsz/node-red-starter-googleappengine.git

### CI/CD設定
CI/CDの変数を設定します。Gitlabプロジェクトより、左メニューの設定 > CI/CD を開き、Variablesセクションを展開、以下変数を設定ください。

| キー | 値 |
| ------ | ------ |
| GCP_PROJECT_ID | GCPのプロジェクトID |
| GCP_SERVICE_ACCOUNT | GAEへのデプロイ時に使用するサービスアカウント　キーJSONファイル内本文をコピーし設定 |
| NODE_RED_CREDENTIAL_SECRET | Node-REDフロー暗号化キー（任意の値） |
| NODE_RED_USE_EDITOR | Node-REDのエディタ使用可否（デフォルトはfalse） |
| NODE_RED_USE_APPMETRICS | AppMetricsの使用可否（デフォルトはfalse） |
| NODE_RED_USERNAME | Node-REDのエディタのログインユーザーID |
| NODE_RED_PASSWORD | Node-REDのエディタのログインユーザーPW |
| NODE_RED_GCS_ACCOUNT | Node-RED storageModuleで使用するGCS用サービスアカウント　キーJSONファイル内本文をコピーし設定（未設定の場合はlocalStorage） |
| NODE_RED_GCS_LOCATION | Node-RED storageModuleで使用するGCSのBucketロケーション（デフォルトはASIA-NORTHEAST1） |
| NODE_RED_LOG_LEVEL | Node-REDのログ出力レベル（デフォルトはinfo） |
![スクリーンショット 2020-12-10 22.06.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142110/c55ba1cd-0474-0cbe-1a7a-9ca2d83cfd85.png)


## Node-RED開発環境の準備
### ローカル環境へインストール
以下コマンドでインストールください。

```
sudo npm install -g --unsafe-perm node-red
```
参考： https://nodered.jp/docs/getting-started/local  

### Node-REDプロジェクト機能有効化
<インストール先>/settings.jsファイルの一番下にプロジェクト機能のセクションがあります。デフォルトは false になってますので、ここを true に変更し、プロジェクト機能を有効化します。

```
// Customising the editor
editorTheme: {
    projects: {
        // To enable the Projects feature, set this value to true
       enabled: true
    }
}
```

### Node-REDを起動
以下コマンドで起動ください。

```
node-red
```

### プロジェクトをクローン
ブラウザでローカルのNode-REDへアクセス`http://127.0.0.1:1880`、右上のハンバーガーメニュー > プロジェクト > 新規　を開き、「プロジェクトをクローン」を押下、以下必要情報を入力し、「プロジェクトをクローン」ボタンを押下ください。

| 項目 | 値 |
| ------ | ------ |
| プロジェクト名 | 任意 |
| GitリポジトリのURL | 先程インポートし準備したGitlabリポジトリのURL |
| ユーザー名 | GitlabのログインユーザーID |
| パスワード | GitlabのログインユーザーPW |

### フロー暗号化設定
ノードに設定するAPIトークン等のセキュリティ情報を暗号化するため、フローの暗号化設定を行います。右上のハンバーガーメニュー > プロジェクト > 設定 > 左タブの設定　を開きます。そのウィンドウの右上に「編集」ボタンがありますので、こちらから設定ください。

| 項目 | 値 |
| ------ | ------ |
| 新規の暗号化キー | GitlabのCI/CD変数にて設定したフロー暗号化キーと同じ値 |

以上で準備は完了です。

# GAEへデプロイ
続いてフローをGAEへデプロイします。GitlabのMasterにPUSHされたタイミングでCI/CDが動作するよう構成されてますので、まずは変更をGitにPushします。
準備が完了した初期状態では、Node-RED上には`Hello, Node-RED-Starter-GoogleAppEngine !!`と答えてくれる動作確認用のフローがあります。
![スクリーンショット 2020-12-10 22.39.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142110/d6320c15-169b-10e9-af02-8394e14b0e81.png)

これを位置の変更など少しだけ変更し、commit/pushしましょう。Node-RED画面右側のサイドバーの「履歴」タブを開きます。「ローカルの変更」セクションを確認し、対象の変更を追加します。全ての場合は「全て」ボタンを押下し「コミット対象とする変更」に追加します。コミットコメントを入力し、「コミット」ボタンを押下します。「コミット履歴」セクションを開き、「↑↓」ボタンを押下、プッシュ先のリモートブランチを選択し、「プッシュ」ボタンを押下します。これでリモートGitブランチへのプッシュが完了です。
![スクリーンショット 2020-12-10 22.36.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142110/a73d7205-4f8e-e9f0-5b69-91a43ac92749.png)

PushしますとGitlabでCI/CDジョブが走り始めます。GAE Flexible環境なのでデプロイにちょっと時間がかかりますが、、、最後に`Job succeeded`と出てくれば完了です。
![スクリーンショット 2020-12-10 22.59.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142110/f5c0525a-231c-ea7a-8823-4068fc5642fe.png)

# 動作確認
## HTTP Requestを投げてみる
動作確認用のフローのendpointにrequestを投げてみます。ブラウザを起動し、`https://xxxxxx/hello`にアクセスください。以下のようなメッセージが表示されれば成功です。
![スクリーンショット 2020-12-10 23.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142110/0fd268dd-ca24-f3a5-03fa-427150be7609.png)

## Cloud Loggingの確認
Node-RED-Starter-GoogleAppEngineのアプリケーションログは、Cloud Loggingに対応してます。Loggingの画面、ログフィールドのLOG_NAMEを`winston_log`で絞り込んでください。そうすると、図のようなAP起動ログが確認できるかと思います。
![スクリーンショット 2020-12-10 23.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142110/88295300-1f6c-9f09-a2b2-70d660d236a3.png)

## Cloud Storageの確認
GCSには、Node-REDのフロー定義が保管されます。デフォルトの設定でデプロイした場合、以下にフローが保管されますので確認してみましょう。

- Bucket：`<GCP PJID>-gae-<GAE サービス識別子>-node-red`
- フォルダ：`GAE バージョン名`

![スクリーンショット 2020-12-10 23.32.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142110/f1039751-53af-0e6a-075b-a1f461eb89b6.png)

GAE上のNode-REDのEditorでフローに変更を加えた場合、ここに保管されているフロー定義に保管されます。このような形でサーバーレスサービスであるGAE上の変更を永続化しています。

# まとめ
いかがでしたでしょうか。GAE環境でもNode-RED、ぜひ使ってみてください！