serverless framework with AWS(Cognito/AppSync/DynamoDB)
ゴール
serverless frameoworkを使った下記の構成のプロジェクトを読める・理解する必要が出てきたので調査する。
- AppSync
- DynamoDB
- Cognito
理解するために一度自分で基本構成を組んでみつつ動く所までやる。
参考リンク系
手順についてはこの記事に沿いつつ途中わからなくなった所のログをまとめています。
serverlessをざっくり理解するために下記を
appsync起動以降のlocalでの起動やテストはこれが参考になる
serverless framework用のAWS IAM
- AdministratorAccessを付けるのが簡単
- ちゃんとアクセス付けたい場合JSONを使ってユーザー作ると良さそう
- https://gist.github.com/ServerlessBot/7618156b8671840a539f405dea2704c8
- これはメンテされているのかよくわからないのでちゃんと必要な分だけに編集すると良いのかも
~/.aws/credentials
にprofileを足してproviderにprofileを設定する
ついでにregionも設定する
provider:
...
region: ap-northeast-1
profile: devProfile
Resources
resourcesは大体CloudFormationから来ているので、値を調べる場合はCloudFormationのDocにいく
DynamoDB
BillingMode
- PROVISIONED -> Provisioned Mode(予めスループットを抑える)
- PAY_PER_REQUEST -> 抑えないかわりに高くなる
お試し中はPAY_PER_REQUESTでいい気がする。
ProvisionedThroughput
BillingModeをPAY_PER_REQUESTを設定していると
ReadCapacityUnits / WriteCapacityUnitsは自動的に0になる。
Cognito
Cognito::UserPool
emailでログインする、等後で変更できない要素がいくつかあるので注意する。
Cognito::UserPoolClient
Cognito::UserPoolGroup
AWS Consoleから作った後にパスワード変更が必要
aws cognito-idp admin-set-user-password --user-pool-id <your user pool id> --username user1 --password password --permanent
実際にはこんな感じだった
aws cognito-idp admin-set-user-password --user-pool-id <pool_id> --username useruser --password testuser --permanent --profile=<profile_name> --region ap-northeast-1
IAM Role
ARN
RoleName参考にしている記事では
RoleName: 'AppSyncLoggingServiceRole-${self:provider.stage}'
となっていたものの、ここはstageの分岐が必要なのかな…?
AppSync
全部読んだほうが良さそう
ページ分割/リレーション的
Mapping Templates
VTL ( Apache Velocity Template Language )
VTLプログラミングガイド
UpdateのDyanmodb template(全属性更新)
渡された値のみの更新(vtlえぐい)
IDE
VSCode
プラグインがありそうだった
IntelliJ ( Jetbrains )
File Types内にVelocity Templateがあるのでパターンに*.vtlを足す
DynamoDB
テーブルを減らすためには目指す場合はGSI Overloadingという手法がほとんどの場合必要になってくる気がした。GSIは上限があるのでGSIの数で殴るのは怖い。
テーブルが減らせている場合複数Attributeが横に伸びていくのでNoSQLWorkbenchでFacetなどを使った管理をしたほうが良さそう
大きいデータが有る場合はフィルタ検索範囲のデータサイズでRCUを消費するので、HTML/Messageなどで中身が大きい場合にはテーブルを分割しないとRCUが吹っ飛ぶ
検索部分一致などはないある。
Valid Values: EQ | NE | IN | LE | LT | GE | GT | BETWEEN | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | BEGINS_WITH
日付も多分timestampなどで記録しないと範囲の絞り込みが厳しい。 ISO8601に従っている場合比較演算子が効くらしい
全文検索がしたい場合はElasticSearch等の全文検索エンジンを使える予算があればそこにDynamodb Streamから流す
転置インデックスによる検索の模索
まとめ
AWSとCloudFormation
AWSの基礎知識とCloudFormationの設定値をひたすらに調べる必要がある。
とはいえこれはしょうがないので適宜Inputする必要がある。
DynamoDB
一番苦労した、とはいえRDB系の頭からNoSQL系入ってくると大体こうなるのでは。
- 設計が難しい
- 適当にTable/Request作っているとどんどん課金額が上がりそう
- 色々苦手な部分や制約が多くDynamoDBが必要という明確な理由がないとRDB系のほうが圧倒的に良さそう
- 集計系が苦手
- 普通のページャは作れない?
- batchUpdate/TransactWriteItemsなどのオペーレーション数制限
苦手・制約については他サービスとの連携・組み合わせで解決できるものの、ちゃんと予算がないと厳しい。
自分の近々の身の回り(個人/仕事)、そこまで予算がない、もしくは後で問題になりそう、な気配しかないのでDynamoDBのデメリットのほうが上回ると思ったので一旦興味がなくなってしまった。
NoSQLだから設計が後付でやりやすいのかなとか思っていたが逆でRDB系より初期要件が明確になっている必要がある。
結構ゲーム系では採用するのはいいと思うものの、Webの開発、かつ個人開発やユーザー需要が見えない(完全に新規かつリーチするユーザーを抱えていない)開発ではあまり採用したくないなと感じた。DynamoDBの特性を理解しつつやれてそれで要件を満たせるならDynamoDBのほうが安い、とは思うもののそれで要件が満たせるサービスとは…?という感じだった。
受託での採用も結構要注意な気がしていて、NoSQL/DynamoDB使うと先に握ったほうが良い気がした。
あまり相手がピンと来ていない場合は、後に他サイトを参考に制限や苦手な部分を要求されやすい気がしていて、そこへの対応コストもあまりピンと来ないと思われる。
(追記)
Amplifyで自動生成されるTableは割とRDB的にTableが作られていく。これなら割と有りな気もしたもののこれで良いのかな…?深いネストがなければ大丈夫なのかな感がある。
VTLは結構これで生成されているものを参考にしたほうが早そうな感がある。そうすると自力appsyncの意味が感がある…。
というよりこのAmplifyの設計とDynamoDBのベストプラクティスな設計の関係性とは…感。
Serverless Framework
設定値が難しいので最近サポートされているts形式で設定ファイルを書いてみたものの、型のサポートがCloudFormation周りはほとんどなく、世の中のExampleはyml形式なのでymlにしたほうが良さそうだった。
AWSだけなら差異は確認しないといけないもののCDKとかのほうが気持ちよくかけそうな感じがある(TS前提)。デプロイ戦略周りが変わってくる・違いがあるというようなことをどこかの記事でみたものの失った。
構成自体
会社運用であれば色々可能性はあるものの、DynamoDBの強いひとがいない、小規模・個人開発、ではなんとなく厳しいのではと思ってしまった。(DynamoDBに慣れていてさくっと設計、制限等も頭に入っている場合は全然別だと思う)
リポジトリ
コードただの構成作ったくらいなもののAWS怖い、レベルからこの程度までである程度理解しつつ、だと50時間くらいかかった。いい勉強にはなったし、謎のAWS怖いアレルギーから開放されたのでよかった。