・API毎に個別の設定がどれだけやりたいか
・APIにIAM認証をかけるかどうか(最終的にAPI内でIDトークンの検証があるとして)
■ SAM
メリット
・メソッドごとにポリシー、ラインタイムのメモリ容量とかきめれる
・CloudFormationと親和性がある
・メソッド(lambda)が分割せれるので、AWSコンソール上からLambdaを直接修正できるサイズに収まっている可能性がある。
・ログがLambda関数毎になるので見やすい。
デメリット
・必ずLambdaを使うことになるので、Lambdaの制限を超えるAPI(ペイロード上限を超える等)が発生した場合、Fargate等で別の方式を使ってAPIを作る必要が出る
・APIの数が増えると管理になってくる
・APIGateway、Lambdaの数が膨大になる
・template.yamlの中が膨大になる
・↑の結果、mtemplate.yamlのCloudFormationの上限(リソース数等)をこえる
・ベストプラクティス的にはtemplate.yamlをAPI毎に分ける方式のようだが、そうするとローカルでのAPI起動、リリースが大変。ファイル数が凄いことになる
・まー、そうなったら分割しろっていう話かもしれないけど。。
・逆に言うと、1APIずつリリースできたりするので、時には便利ではある。
・Globalsで一括設定出来ないようなものがある場合、一つ一つ設定しないといけなくなる(例:一部のAPIにしか設定したくないようなもの)。最初からそうなっていればいいけど、APIを50個いれた後に追加しないといけないとかが辛い。
・ローカルがDockerで起動するので、winと相性わるい
・docker-toolboxかhyper-vが必須になる。
・hyper-vの場合、virtualboxを捨てる必要あり?
・最近はそうでもない?
・1リポジトリで複数のAPIに対応+共通処理はLayer化しようとすると、アプリ(ソースコード)の構成をちゃんとする必要がある
・アプリ構成のフォーマットを考えたのであまり問題にはならない?
・ローカルで動かす場合もDocker起動になるので立ち上がりが遅い
・lambda_handlerを呼び出すスクリプトファイルを作れば回避可能
・開発用のPCが遅いだけ?
・共通処理をlayerに入れる感じになる
・Layer化に対応したアプリ構成にすることが必要(考えてあるので問題ない?)
・ローカル環境がwindowsである場合、local start-apiしようとすると、dockerコンテナ側がlinuxなので、ライブラリが共用できない
・ただ、最終的にはLinux用のライブラリが必要(Lambda上(AmazonLinux2)で動かすので)になるのでいつかはやる必要ある
・最初からLinuxで動かせという話になるが、SAM localがDockerで起動するため、Docker in Dockerになる
・DockerコンテナないでDocker動かすのは、docker.sockの共有がいいっぽい
・docker.sockの共有(https://qiita.com/sugiyasu-qr/items/85a1bedb6458d4573407 の方法②)
・Windowsでdocker.sockの共有(https://qiita.com/comefigo/items/6394a43b3bd97cde7b17)
・プロビジョニングさせた同時実行など関数毎の設定になる
・とりあえず全体で50本待機させておく、みたいなのが出来なくて、よく呼び出される関数を狙い打ちする形になる。
・要は暖機が大変。ここは普通にネック。
・プロビジョニングされた同時実行は1同時実行当たり、$1~$1.5くらいで結構お高いので注意
・コネクションプールを使用する場合、リスクになりやすい、プールを使用するLambdaの選定が必要
・使用していないLambdaからいつまでもプールが残っているのはまずい
・sam localで実行時にデバッグでブレイクできない。(docker toolboxだけかも知れない)
・hyper-vだとブレイクできた。
・Lambdaの数だけ起動構成がひつようになる(PyCharm)。
・実行環境のプルダウンでLambdaの切り替えできるけど、数増えた時辛い?
・実際に触ってるヤツだけ残しておけば良い気もする。。
・template.yamlの最終型はCloudFormationの参照値だらけになるので、ローカルで起動させるためのtemtemplate.yamlが必要になる。
・Serverlessでも同じ?
・ローカルでFlaskを上げるので問題ない感じはする
■ Serverless framework
※Flask, bottleなどを使う前提
メリット
・ベースとしてFlask、bottle等を使用するため、Lambdaの限界を超える処理(ペイロード上限等)が発生した場合に、EC2、ECSに切り替えやすい
・API群を1つのアプリケーションとして考えられるのでシンプル
・Lambdaが1つで済む
・共通処理をLayerに入れなくて済む
・Dockerに依存しないでローカルでAPIを起動、実行できる
・コネクションプールの管理が考えやすい
・1関数で全てのURLに対応することができるので、API群全体でプールを張るっていうことができる
・URL毎に関数を作ると1URLにつきプールを張っていくことになるので、頻度が低いURLの場合、プールを張らない等、細かい設定が必要
・(使用していないLambdaからいつまでもプールが残っているのはまずい
デメリット
・Lambdaコンソール上から直接修正できない
・量が少なければできるだろうけどその状態はあまり現実的でない
・ログが混ざるので、後からフィルターしやすいようにする必要あり
・ポリシー、ランタイムのメモリ容量等、全体で1つしか設定できない
・APIGatewayも1つになるので、APIGatewayを使ったパスごとの細かい設定は出来なくなる(特定のAPIにはIAM認証をかける等)
・Flaskが必要になるので容量増える
・つってもFlask以外にもライブラリ使うだろうから誤差感あるけど。。
■ 参考
AWSの人のBlog記事(結論的にはServerlessでflaskみたいなのには否定的):https://aws.amazon.com/jp/blogs/compute/best-practices-for-organizing-larger-serverless-applications/