IBM Cloudからの通知を生成AIを使ってわかりやすく - (3)デプロイ＆設定編

# はじめに
※こちらはシリーズとなっており、下記ラインナップの1つ目になります。
「IBM Cloudからの通知を生成AIを使ってわかりやすく」シリーズ
- [(1)通知の仕様編](https://qiita.com/katahiro/items/b9bd400f93d328613cff)
- [(2)Webhookアプリコーディング編](https://qiita.com/katahiro/items/d8048393ce42cf9c5b3b)
- [(3)デプロイ＆設定編](https://qiita.com/katahiro/items/53443fabe2980c2fba03) ← 今ココ

こちらは、前回記事に続いて、コーディングしたWebhookアプリをCode Engineにデプロイして、IBM Cloudの通知先として設定する話になります。シリーズもこれで最後です。

# Code Engineにデプロイする
[README](https://github.com/katahiro-github/cloud-notification/blob/main/README.md)にも記載していますが、下記の手順に従ってください。
(前提条件)
- IBM Cloudで既にCode EngineのProjectを作成済である(まだの方は[こちら](https://qiita.com/Sungyun_Moon/items/217e1646724116ee6465)を参考に作成ください)
- READMEに従ってコードをCloneし、 `.env`ファイルを作成の上で、適切な環境変数を指定している
- IBM Cloud CLIが導入されている(Code Engineのpluginが導入済、まだの方は[こちら](https://cloud.ibm.com/docs/codeengine?topic=codeengine-cli)を参照)

まず、GithubからCloneしたディレクトリで、IBM Cloudにログインします。
```console
ibmcloud login -u [メールアドレス]
```
操作するリージョンとリソースグループを選択
```console
ibmcloud target -r [region] -g [リソースグループ]
```
注意点として、Code Engineはリソースグループの権限が無いと操作できません。Code EngineのProjectを作成したユーザーで実行する場合は問題ないですが、例えばService IDといった特定の要件に合わせたAPIキーを作成して、そのAPIキーでIBM CloudのCLIでログインする場合は、リソースグループへの権限付与を失念してしまいがちなので注意が必要です。

アプリを登録するCode EngineのProjectを選択
```console
ibmcloud ce proj select -n [Project name]
```
`.env`には必要な環境変数が設定されている、という前提で、この `.env` からCode Engineで利用するSecretを作成します
```console
ibmcloud ce secret create -n [secret name] -e .env
```
`.env`の環境変数は`変数名=設定値`というように、`=`の前後に不要なスペースを入れないようにしてください。スペースが入っているとこのコマンドはエラーになります。

Code EngineでFunctionの作成
```console
ibmcloud ce fn create -n [function name] --runtime nodejs-18 --cpu 0.25 --memory 1G --met 120 --env-sec [secret name] --build-source .
```
ここが重要で、いくつかパラメータの指定があるので指定漏れが無いようにしてください。
- `-n` : Functionの名称
- `--runtime` : Code EngineのFunctionのランタイムを指定、Node.jsかPythonしか選べないですが、今回は `nodejs-18`
- `--cpu` : デプロイしたコンテナの割当CPU。Functionで指定できる最小値が `0.25`
- `--memory` : デプロイしたコンテナの割当メモリ。Functionで指定できる最小値が `1G`
- `--met 120` : 最大実行時間。デフォルトの60秒では終わらないことがほとんどなので、最大の120秒を指定
- `--env-sec` : 利用するSecret。先ほど作成したSecretを指定
- `--build-source` : デプロイするソースコードを指定。カレントディレクトリなので `.` を指定

これが問題なく通る場合、コンソールに以下のように表示されます。
※Functionの名称に `temporary-function` を指定
```console
ビルド・プッシュ用に関数「temporary-function」を準備しています ...
機能「temporary-function」を作成しています...
パス「.」からアップロードするファイルのパッケージ化...
ビルド実行 'temporary-function-run-240304-171651118'を送信中...
イメージ 'private.jp2.icr.io/ce--xxxxx-xxxxxxxxxxx/function-temporary-function:240304-0816-wbesj' を作成しています ...
ビルド実行が完了するのを待機しています...
ビルド実行状況: '実行中'
ビルド実行が正常に完了しました。
ビルド実行の状況を確認するには、'ibmcloud ce buildrun get -n temporary-function-run-240304-171651118' を実行してください。
関数「temporary-function」が作動可能になるのを待っています ...
関数「temporary-function」は作動可能です。
OK
詳細を表示するには、'ibmcloud ce function get -n temporary-function' を実行してください。

https://temporary-function.xxxxxxxxxxx.jp-osa.codeengine.appdomain.cloud
```
最後に表示されたURLがデプロイしたアプリのエンドポイントになります。これをメモしましょう。

以後、ソースコードを修正して、その修正だけ適用したい場合は、以下のコマンドでデプロイしなおします。変更しない箇所のパラメータは指定しなければ過去の設定が踏襲されます。
```console
ibmcloud ce fn update -n [function name] --build-source .
```

# IBM Cloudの通知先にWebhookアプリを追加する
先ほどCode EngineのFunctionにデプロイしたアプリをIBM Cloudの通知先に登録しましょう。

IBM Cloudコンソールの右上にあるNotificationのメニューへ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/bd03d741-aee2-d6cb-371b-2708df70db07.png)

遷移先画面右上の「アクション」から「通知設定の表示」へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/549ff014-47a6-b8c5-032f-1fe0ca14e149.png)

遷移先画面下部の「通知配布リスト」の「管理」へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/6776bf85-3460-5bb6-3e8b-0a264cfc3136.png)

遷移先画面「追加」から「Webhook」へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/bad3607a-6ae1-0e27-839a-b6967f7468b8.png)

名前とURLに先ほどデプロイしたFunctionのエンドポイントを指定します。
Bearer認証を設定している場合は、セキュアヘッダーでAuthorizationとBearerのトークンを指定するようにして追加してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/e24ddc16-7ddb-0bf8-69f0-71b24cd6f8c2.png)

これで無事に登録することが出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/dc5a8d2f-018a-40e2-a42e-cee1a03c09b4.png)

設定に問題無いかテストすることが出来るのですが、ここでちょっと罠があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/3c854d53-aace-ee0f-58f7-7ce19cb107c5.png)
テストを選ぶと指定したエンドポイントに以下のような内容がPOSTされます。
```json
{
  "account_id":"039dbe6794084c7cb514a276dd2345da",
  "body":[
    {
      "content-type":"text/html",
      "language":"en",
      "text":"This is a test notification sent to your webhook (test-webhook)."
    }
  ],
  "category":"Account",
  "endTime":1709567800090,
  "severity":"",
  "startTime":1709567800090,
  "state":"",
  "subCategory":"webhook-test",
  "title":[
    {
      "language":"en",
      "text":"Test webhook notification."
    }
  ],
  "updateTime":1709567800090
```
何が罠かというと、 `startTime`といったunixtimeですが、テストのときはミリ秒まで含まれた単位で送られます(13桁)。一方通常の通知の際は10桁のミリ秒無の桁数で送られてきます。今回のソースコードはミリ秒が含まれていない10桁で動作する形にしているので、テストで動作させた結果、開始日付等がおかしな情報になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/3774cbee-2aab-fa93-9d1a-302a98756dc6.png)

ともあれ、設定直後にメンテナンスの通知がありましたが、問題なく動作していました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/79e82def-e47f-b859-f48c-3942fbf8b6fb.png)

単純に英語の通知を読むよりも格段にぱっと見で理解できる内容になりました。

# 課金について
watsonx.aiとCode Engineを使った今回の仕組みで課金されるポイントは3点あります。
- watsonx.aiの利用
- Code Engineの利用
- Container Registoryの利用

## watsonx.aiの課金
あくまで経験ベースですが、2024年2月は約190件の通知を処理させた結果、$0.87の課金が発生しました。今回利用しているモデルは `meta-llama/llama-2-70b-chat` で、Watson Machine Learningの中でもClass2に分類され、比較的安価に使えるモデルになります。

## Code Engineの課金
190件の通知を処理したとした場合、以下のリソースを使ったことになります。
- 0.25 vCPU × 120 seccond × 190 = 5,700 vCPU/秒
- 1G RAM × 120 seccond × 190 = 22,800 GB RAM/秒

Code Engineは月に 100,000 vCPU/秒、200,000 GB RAM/秒までは無償なので、無償枠の範囲内ですね。(他に動作させていた場合を除く)

## Container Registryの課金
今回のコードを配置した場合の容量は31KBでした。
Container Registryは500MBまでStorageは無償です。余裕で無償内です。

月に$1でここまで出来れば、割と良いのではないかと、自分ながら思ってしまいます。

# さいごに
いかがでしたでしょうか？生成AIを便利に使う方法の1つとして要約といったものがありますが、それをIBM Cloudから送られる通知に利用してみました。

もちろん、生成AIが作る文章なので、その正確性や、変な日本語になる、もしくはうまく翻訳等ができないこともあり得ます。ただ、その分を差し引いても、要約タスクをある程度自動化できるのは強いですね。

IBM Cloudから送られる通知は英語のため、つい見逃してしまったり、ちゃんと内容を読まないケースがあるかもしれませんが、この方法を活用することで、通知内容で取るべきアクションが何か、即検討できる環境が実現できると幸いです。

# シリーズのリンク

https://qiita.com/katahiro/items/b9bd400f93d328613cff

https://qiita.com/katahiro/items/d8048393ce42cf9c5b3b

https://qiita.com/katahiro/items/53443fabe2980c2fba03