Closed8

serverless framework with AWS(Cognito/AppSync/DynamoDB)

isopppisoppp

ゴール

serverless frameoworkを使った下記の構成のプロジェクトを読める・理解する必要が出てきたので調査する。

  • AppSync
  • DynamoDB
  • Cognito

理解するために一度自分で基本構成を組んでみつつ動く所までやる。

参考リンク系

手順についてはこの記事に沿いつつ途中わからなくなった所のログをまとめています。
https://www.ragate.co.jp/blog/articles/4064

serverlessをざっくり理解するために下記を
https://serverless.co.jp/blog/25/

appsync起動以降のlocalでの起動やテストはこれが参考になる
https://qiita.com/G-awa/items/095faa9a94da09bc3ed5

isopppisoppp

serverless framework用のAWS IAM

https://www.serverless.com/framework/docs/providers/aws/guide/credentials/#create-an-iam-user-and-access-key


~/.aws/credentials にprofileを足してproviderにprofileを設定する
ついでにregionも設定する

provider:
  ...
  region: ap-northeast-1
  profile: devProfile
isopppisoppp

Resources

resourcesは大体CloudFormationから来ているので、値を調べる場合はCloudFormationのDocにいく

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/

DynamoDB

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html

BillingMode

  • PROVISIONED -> Provisioned Mode(予めスループットを抑える)
  • PAY_PER_REQUEST -> 抑えないかわりに高くなる

お試し中はPAY_PER_REQUESTでいい気がする。

ProvisionedThroughput

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-provisionedthroughput.html

BillingModeをPAY_PER_REQUESTを設定していると
ReadCapacityUnits / WriteCapacityUnitsは自動的に0になる。

isopppisoppp

Cognito

Cognito::UserPool

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpool.html

emailでログインする、等後で変更できない要素がいくつかあるので注意する。

Cognito::UserPoolClient

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpoolclient.html

Cognito::UserPoolGroup

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpoolgroup.html

AWS Consoleから作った後にパスワード変更が必要

https://stackoverflow.com/a/56948249/12981245

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
isopppisoppp

DynamoDB

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/best-practices.html

https://www.youtube.com/watch?v=Wd5gbLQ2a1E&feature=emb_logo

https://mizumotok.hatenablog.jp/entry/2019/08/13/172430

https://www.ragate.co.jp/blog/articles/3278


テーブルを減らすためには目指す場合はGSI Overloadingという手法がほとんどの場合必要になってくる気がした。GSIは上限があるのでGSIの数で殴るのは怖い。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-gsi-overloading.html

テーブルが減らせている場合複数Attributeが横に伸びていくのでNoSQLWorkbenchでFacetなどを使った管理をしたほうが良さそう

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/workbench.settingup.html

大きいデータが有る場合はフィルタ検索範囲のデータサイズでRCUを消費するので、HTML/Messageなどで中身が大きい場合にはテーブルを分割しないとRCUが吹っ飛ぶ

検索部分一致などはないある。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/APIReference/API_Condition.html

Valid Values: EQ | NE | IN | LE | LT | GE | GT | BETWEEN | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | BEGINS_WITH

日付も多分timestampなどで記録しないと範囲の絞り込みが厳しい。 ISO8601に従っている場合比較演算子が効くらしい

https://stackoverflow.com/a/30713517/12981245

全文検索がしたい場合はElasticSearch等の全文検索エンジンを使える予算があればそこにDynamodb Streamから流す

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions

転置インデックスによる検索の模索
https://dev.classmethod.jp/articles/dynamodb-inverted-index/

isopppisoppp

まとめ

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に慣れていてさくっと設計、制限等も頭に入っている場合は全然別だと思う)

リポジトリ

https://github.com/isoppp/sandbox-serverless-appsync/

コードただの構成作ったくらいなもののAWS怖い、レベルからこの程度までである程度理解しつつ、だと50時間くらいかかった。いい勉強にはなったし、謎のAWS怖いアレルギーから開放されたのでよかった。

このスクラップは2020/12/06にクローズされました