Smart Territory Framework をデプロイしてみる

## やってみたこと

FIWARE を AWS 上で簡単に動かしたいと思い、いろいろ調べてます。
Orion Context Broker はコンテナ化されているので、これを Fargate とかで動かす方法を探してみました。

[スマートシティの 都市OS におけるデータ連携に AWS と FIWARE を利用する方法](https://aws.amazon.com/jp/blogs/news/aws-and-fiware-to-buid-cityos-for-smartcity/)
この記事を見ると、それらしい候補が2つあるようです。

- [Smart Territory Framework (STF)](https://aws.amazon.com/jp/blogs/news/aws-and-fiware-to-buid-cityos-for-smartcity/#:~:text=Smart%20Territory%20Framework%20(STF))
    - コンテキストブローカーは Orion ではなく Scorpio というものが使われている
- [FIWARE Orion Context Broker and Cygnus on AWS](https://aws.amazon.com/jp/blogs/news/aws-and-fiware-to-buid-cityos-for-smartcity/#:~:text=FIWARE%20Orion%20Context%20Broker%20and%20Cygnus%20on%20AWS)

STF の方がいろいろと揃っていて良さそうな雰囲気なので、まずは STF を使ってみることにしました。

結論としては、STF は私の用途には合わないと分かったため、いまはもう片方について調べようとしています。
この記事では、STF が私に合わなかった理由と、STF をデプロイするまでのメモを残しておきます。

## とりあえず STF をデプロイする

[STF の GitHub リポジトリ](https://github.com/aws-samples/aws-stf-core-scorpio)にある README を軽く見たところ、コンテキストブローカーを AWS のサーバレスなサービスで構成できるらしいです。
README に書かれたシステム構成図を見ると、以下のような感じです。

- Scorpio Context Broker のコンテナを Fargate で構成する
    - [Scorpio コンテキストブローカーについて](https://jpn.nec.com/oss/community/hosting-oss-projects/scorpio-context-broker.html)
    - [Apache Kafka](https://oss.nttdata.com/kafka/kafka.html)で実装されているらしい
    - Fargate の利用料が発生する
- DB 部分は Aurora で構成する

AWS 素人なもので Kafka と Fargate の関係がよく分かってませんが、とりあえずデプロイして放置してみて、お金がかかるようだったら破棄するという無駄遣いスタイルでいってみることにします。
（気が向いたときに趣味で触ってみるという程度なので、ほとんどの時間は何も触らないまま放置することになります。放置中にお金がかかるようだったら止めたいと思います。）

### 準備

必要なもの

- AWS アカウント
- 管理者権限を持つ IAM ユーザ
- AWS CDK

とりあえず使ってみたいので、軽くドキュメントを読んだらデプロイしてみます。
Fargate の利用料金がかかるため、いざというときはすぐに破棄できるよう、デプロイと破棄の方法だけ押さえておきます。

デプロイ:
```sh
cdk deploy
```
※事前に `npm install` と `cdk bootstrap` を実行しておくこと。詳細は [STF の README](https://github.com/aws-samples/aws-stf-core) を参照

破棄：
```sh
cdk destroy
```

### デプロイ

[GitHub リポジトリ](https://github.com/aws-samples/aws-stf-core-scorpio)からプロジェクトソースを取ってきて、[Getting started の説明](https://github.com/aws-samples/aws-stf-core-scorpio#getting-started)を見ながら parameter.ts ファイルの設定を確認します。
とりあえず、何も変更せずに `npm install` → `cdk bootstrap` → `cdk deploy` と進んでみます。

なんか進んでいるっぽい。
AWS マネジメントコンソールで Cloud Formation を確認すると、StfCore ナントカというスタックが動いてます。
```sh
StfCore: creating CloudFormation changeset...
[██████████████▌···········································] (1/4)

2:43:30 PM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack | StfCore
2:43:35 PM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack | ScorpioServerless....estedStackResource
```
README の説明にも書かれていますが、デプロイには１時間くらいかかるとのことで、48分ほどかかりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72641/3044fa2c-d53b-0c56-2def-9c09e4db70a3.png)

とりあえず、デプロイしたばかりの状態で 1.6ドルほどかかりました。（デプロイするまではほとんど無課金状態だったので、課金分はほぼ今回のデプロイ分のはず）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72641/d07b7efb-5a1d-50dc-457d-8c426c6e2136.png)
EC2がいるのがなんとなく気になる（何もしなくてもお金がかかりそう）ところですけど、しばらく放置して料金の様子を見てみます。（その間に使い方などを調べる）

数時間放置してたら、今月の請求予測が1700円を超えてきました。（予測なので実際は1700円に達してませんが、ほっといたら行きそう）
これはちょっと良くないので、すぐに破棄して設定を見直します。

### parameters.ts の見直し

AWS の利用料に関係しそうな設定項目は、以下のあたりかなと思います。

- stf_scorpio
    - aurora_serverless
        - これを true にすると、PostgreSQL の RDS インスタンスを作らず、Aurora のクラスタを作るらしい？（Aurora よく分かってない）
        - Aurora は書込みが無料で、月100GBまでの読出しが無料らしいので、ちょっと使ってみる程度なら Aurora が良さそう。ということで Aurora を使うことにする。
    - aurora_scaling: Aurora のスケーリングに関する設定みたい。とりあえずデフォルトのままとする。
    - rds_instance_type: RDS のインスタンスで、デフォルトは t4g.small
        - 無料枠で使える t3.micro に変更すると良さそうだけど、今回は RDS を使わないので変更しない
    - rds_storage_type: gp3 のままでよさそう（無料で使えそう）
    - kafka_instance_type: ECS で動く Scorpio のインスタンスだと思う
        - [Kafka は EC2 のインスタンスが作られるらしい](https://docs.aws.amazon.com/ja_jp/msk/latest/developerguide/msk-create-cluster.html#:~:text=%E3%82%89%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82-,%E3%83%96%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%BC%E3%82%BF%E3%82%A4%E3%83%97,-Amazon%20MSK%20%E3%82%AF%E3%83%A9%E3%82%B9)ので、たぶん EC2 の無料枠である t2.micro とか t3.micro にしとけばいいと思ったら、micro という選択肢がないみたい・・（最小で small）
        - 仕方ないので、デフォルトの kafka.t3.small を使うことにする
        - Kafka 自体、コストパフォーマンス関係のいろんな設定ができるみたいなので、もっと調べれば最適な構成が見つかりそうな気がする
    - fargate_desired_count: ？ Kafka のインスタンス数の最小値？1でも良さそうな気がするけど、デフォルトで2になってるので、とりあえず2のままにしておく。

結局、DB に Aurora を使うように変更しただけですが、これでもう一度デプロイしてみます。
たぶん、Kafka はリクエストを投げない限り動かないはずです。なので、~~RDS が無くなれば、放置してる分にはお金かからないはず・・~~
> RDS と Aurora の理解が不十分でした。[こちらの記事](https://www.ashisuto.co.jp/cloud/aws/pr/aurora-column-part1.html)を参考にすると、Aurora は RDS のサービスの一種で、基本的に RDS の仕組みで動くものらしいです。なので、Aurora も基本的には RDS と同じ仕組み（DBインスタンスに対する従量課金）で課金されることになります。

ということは、Aurora をやめて RDS のインスタンスを t3.micro にするのが一番いいのでは？
ということで、以下の設定でもう一度デプロイしてみます。
ちなみに、`aurora_serverless` を true にしてデプロイしたところ、Cloud Formation のスタックが途中で止まってしまいました。（失敗したわけではないのですが、3時間くらい経過しても進まなくなりました）
[こちらの記事](https://qiita.com/nmatsui/items/4e8c782c32a6939ad18e#%E6%B3%A8%E6%84%8F)によると、私用する AWS のリージョンの問題かもしれません。（詳しくは調べてません）

最終的なパラメータは、以下のようになりました。
<Details><Summary>parameter.ts</Summary>

```ts:parameter.ts
 import { Aws } from "aws-cdk-lib";
import { InstanceClass, InstanceSize, InstanceType } from "aws-cdk-lib/aws-ec2";
import { AuroraCapacityUnit, StorageType } from "aws-cdk-lib/aws-rds";

export const Parameters = {
    stf_iot: {
        new_bucket: true, // If true, the stack will create the bucket for the STF IoT DataLake. Set to false if you have already a bucket created. 
        bucket_name: `stf-iot-datalake-${Aws.REGION}-${Aws.ACCOUNT_ID}`, // Default name, change only if needed.
        shadow_prefix: "Stf",
        sqs_iot_queue_name: `StfIoTQueue-${Aws.REGION}`, // Default name, change only if needed.
        smart_data_model_url : 'https://raw.githubusercontent.com/smart-data-models/data-models/master/context.jsonld',
        timeout: '0', // Timeout for the API call in the Lambda that sync with context broker. Has to be a string to pass it in env variable 
        shadow_indexing: false // Activating Fleet Indexing for the shadows will occur costs, see https://aws.amazon.com/iot-device-management/pricing/ 
    }, 
    stf_scorpio: {
        image_context_broker: 'public.ecr.aws/scorpiobroker/scorpio-aio:latest', // Link to ECR Public gallery of Scorpio Broker image.
        rds_instance_type: InstanceType.of( InstanceClass.T3, InstanceSize.MICRO), // see https://aws.amazon.com/rds/instance-types/
        rds_storage_type: StorageType.GP3, // see https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Storage.html
        dabaseName: 'scorpio',
        aurora_serverless: false, // If false, this creates a RDS PostgreSQL Database instance. If true, this creates an Aurora Cluster.  
        aurora_scaling: {
            maxCapacity: AuroraCapacityUnit.ACU_4,
            minCapacity: AuroraCapacityUnit.ACU_2      
        },
        kafka_config_name: `stf-kafka-config`,
        kafka_number_nodes: 2,
        kafka_version: "3.3.1", // see https://docs.aws.amazon.com/msk/latest/developerguide/supported-kafka-versions.html  
        kafka_instance_type: "kafka.t3.small", // see https://docs.aws.amazon.com/msk/latest/developerguide/bestpractices.html
        kafka_cluster_name: 'ScorpioCluster', 
        kafka_storage_size: 100, //  see https://docs.aws.amazon.com/msk/latest/developerguide/bestpractices.html
        fargate_desired_count: 2
    },
    vpc_link_name: 'scorpio-serverless-vpc-link'
}
```
</Details>

とりあえず、これでデプロイして様子を見ます・・

## その後

デプロイして様子を見ようと思い、その間に料金について詳しく調べてみました。
どうやら、Kafka は放っておいてもインスタンスの利用料がかかるらしく、今回の構成である t3.small の場合、1か月で約87ドル（1万円以上！）かかるようです。デプロイする前にちゃんと調べておくべきでした・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72641/d0627997-ac87-9c19-2dbe-9037a8e32012.png)

すでに丸一日放置していて、何もしてないのに3ドルほど課金されてます。
気が向いたときに触る程度で、普段は放置状態になることを考えると、ほとんど何もしないのに月1万円以上取られるのはさすがに無理なので、即刻破棄しました。
（たぶん、RDS の方は無料枠が適用されるんじゃないかと思いますが・・）

[MSK Serverless だと何もしなければお金かからないみたい](https://aws.amazon.com/jp/blogs/news/amazon-msk-serverless-now-generally-available-no-more-capacity-planning-for-your-managed-kafka-clusters/)なので、できれば Serverless で構成したいところです。ですが、いまのところ STF で MSK Serverless を使う方法が分かってません。

ということで、STF を使うのは諦めて、このメモはいったん終了です。

# 参考
- [Smart Territory Framework (STF)](https://aws.amazon.com/jp/blogs/news/aws-and-fiware-to-buid-cityos-for-smartcity/#:~:text=Smart%20Territory%20Framework%20(STF))
- [FIWARE Orion Context Broker and Cygnus on AWS](https://aws.amazon.com/jp/blogs/news/aws-and-fiware-to-buid-cityos-for-smartcity/#:~:text=FIWARE%20Orion%20Context%20Broker%20and%20Cygnus%20on%20AWS)
- [OSS貢献活動 NECが公開するオープンソース Scorpio NGSI-LD Context Broker](https://jpn.nec.com/oss/community/hosting-oss-projects/scorpio-context-broker.html)
- [NTT データ：Kafkaとは](https://oss.nttdata.com/kafka/kafka.html)
- [Amazon Auroraとは？特徴、RDSとの違い、料金計算方法を解説【Amazon Aurora入門】](https://www.ashisuto.co.jp/cloud/aws/pr/aurora-column-part1.html)
- [AWS Smart Territory FrameworkでFIWAREを試してみた（その1：ブローカー）](https://qiita.com/nmatsui/items/4e8c782c32a6939ad18e)