みなさんLambda好きですか、Lambda。
インフラやバックエンドの人は意外と好きですよね。まあ、我々が書くのはワンショットジョブみたいな運用ベースの処理をさぱっと実行できる手順書として作ることが多いかとは思います。
なんせ、余計なこと考えなくていいですしね。ユニットテストコードとか考えたりしませんし、ログは勝手にCloudwatch Logsに送られるし、終わったら勝手に死ぬし、失敗したら勝手にリトライするし、うっかり無限ループ書いてても待てば止まるし。
適当にコード書いてエラーをprint debugするようなインフラ土人には救いの神です。
本番と検証だってLayer割付で切り替えればいいし、インターフェースはAPI Gatewayにでもやらせればいいし、そもそも僕らの作業でAPI叩くくらいならマネジメントコンソールなりAWS CLI叩いてinvokeするほうが速い。ほぼ常時開いている、一般人には何しているのかよくわからない黒い画面には適当なファンクション叩くスクリプトがぼろぼろ転がってたりしますし。
おかげでとりあえずimport boto3;って書く癖がついてますが。面倒だから空のテンプレートの冒頭に
import boto3;
s3 = boto3.client('s3')
まで書いておいてくれ(ものぐさ)。あ、AWS_DEFAULT_REGIONは実行時環境変数のとこにとりあえずキーだけ書いておいてくれるとTypoが回避できるんで助かる。
ついでにos.environmentも忘れやすいから頼む。あ、あとjson.loadとjson.dumpがどっちがどっちかわかんなくなるから冒頭にeventを適当な変数にjsonで読み込んどいてくれないかな!?
※もうそこまで言ったら手元にテンプレート用意しとけという話である。
さて、そんなLambdaですが、インフラ畑の人間にとっては手軽に使えるジョブ実行ツールという扱いで気軽に扱いはするものの、開発から「Lambdaってどーよ」って言われると、Serverless進んじゃうとインフラのお仕事が減る、という素敵な循環に陥ります。
いや別にLambda作るよ!って言ってあげればいいのかもしれませんが、コード書くのがしぬほど嫌いな私としてはできればコード書かなきゃならない事態は避けたい。
さて、そんなLambdaですが、そのバックエンドにはコンテナ技術が走っており、実態はFirecrackerというアプリケーションです。これはAWSさん謹製ですが、Azureでもにたよーなものが作られていますね。
さてさて、こういうイベントドリブンなファンクションをFaaSなんて言いますが、これ、レガシーなphpなんかでがっつりフレームワーク使ってきた開発の方には今一つイメージが正確につかみにくいようです。
どうやってデバッグすればいいの? デプロイしろwwwww
ローカルでデバッグしたい! ローカルデバッグがいるような巨大なコードをLambdaにシュリンクするんじゃない、もっと分割するんだ!(原理主義者
みたいなことが直感的に理解されない。まあSAMとか使えばlocal invokeもありますけれど。そもそもテストコードすら含有させないような仕掛けに近く、テストはAWSからテストイベント放り込んで走ってもらえ、みたいな話でもある。まあ乱暴っちゃあ乱暴な話なんで、ローカルテストやりたい、はわかりますが、エコシステム的に作ってたらLambdaだけ実行できたってしょうがないしなぁ…。
てことはローカルテスト用のテストコード書いてるのか、みんな。偉いな。私はデプロイしちまえ!になっちまうんだが…。
まあ、ね。気持ちはわかるw わかるんだよね。私もはるかうん十年以上前にオブジェクト指向に触れた時になんだこのキチガイ何言ってるのかわかんね。ってなりましたから。そりゃCのファンクションとポインタとメモリ操作の世界の人にオブジェクトとクラスとメソッドとか言われたって知らねぇよ、なんだよそれ。
結局のところ、マイクロサービス、というもの(思想)を正しく理解しているか、という問いに近いんですよね、これ。マイクロサービスは実装の形態を示したものではなく、あれは思想に近しい、と思う。
Dockerコンテナもマイクロサービスの実装(思想の実現手段)ではあるんですが、よりそれを推し進めてみたら、モノリシックである必要性なんか皆無だった、というのが実態としてある、ということを「現在の状況から」読み解くことができるか、という点を問われているのがLambdaへの理解度、というものではないかと。
DBへのデータモデルの反映とかどうするんですか?
とか聞かれると、まず、「なぜデータモデルというものがあるのか」という点をどう理解しているのか、と思うわけです。おまじない扱いということだろうか。
これは、フレームワークがORMを走らせるのに、データ構造を知っておかないとできないからデータモデルがフレームワーク内に定義されなければならない、ということだと思っているんですよね、こちらとしては。IaCでいうところの宣言的、というやつですね。
データモデルを定義すること自体が目的なのではなくて、本来の目的はそれを宣言することによって、何ができるか、って話で、それはもうORMが動ける。って話じゃないですか。そうなるとデータモデルがないと困る、どこで定義するんだ、って疑問は、ORMがないとSQL文どうやって書けばいいんだ。って言われているのに近しく聞こえてしまう。
Lambdaファンクションで細切れにされたアプリケーションは、相互依存関係を失います。疎結合だから当たり前なんですが。ファンクション間はメッセージングかAPIで疎通するので、そもそもどれかのファンクションがデータモデルで発行したって「俺はそんなもんシラン」って言われるだけですね。
じゃあ全ファンクションにフレームワークと共通のデータモデル突っ込めば!って言い出したらそれこそマイクロサービスというものを理解していない証左になってしまいます。なんでわざわざ細切れにして小さくしたファンクションに余計なもんぶら下げて重くするのか、理解ができないわけです。
まあ、そこもLayerでやれなくはないですけど、正味のところそこまでする意味ありますかね、というのと、「思想の実現」としてやっているマイクロサービスに、「現実の都合」(作り方がわからないとか、ノウハウやナレッジがない)とかで捻じ曲げようとしているように見える。
それは、理想に向かっている正しい姿だろうか、と思ってしまうんですよね。
基本的なクエリの処理はAPIでやればよいと思いますし、複雑なクエリ投げるにしたって、正しくAPIに実装する、あるいはもうどうしようもないくらいわけわからんやつは(そんなもんWebで作るかなぁ…)、バックエンドにDockerでもEC2でも非同期バッチ処理でも置けばよいでしょう。そんな複雑なクエリの時点でLambdaの実行時間に収まるとも思えないし、そんなもんORMに書かせても効率いいSQLが出てくるなんて思えない。Co-pilotに投げたほうがいいクエリ書いてきそうw
多段クエリなんかならStep Functionsを呼べばよい。そもそもLambdaがRDBMSを呼び出すんじゃない、危なっかしい。DynamoDB使えw
要するに、フレームワークで楽してた部分を、全く新しい概念で実装するんだから一回そこを捨てて、脳内の概念構造をいったん入れ替えないといけない。別にそれをやったからってレガシーなコードが書けなくなるわけじゃない。
だってそうでしょう。
手続き型ファンクションでやってたやつがオブジェクトのクラス/メソッドで書くのに慣れたからって、ファンクション書かないかって言ったらそんなことないし、手続きが適している場面だってあるでしょう。メモリ制限がくっそキツいとか。EmbeddedなんてCですら不適格なんて言われた時代もあったわけで。今でもだろうか。
ぼくらインフラだって、クラウドが優れていることは認めているし、クラウドでやるのがとっても楽なのも事実だけど、オンプレミスでなければ解決できない課題、というものもあるし、その時はオンプレミスを選択する。ハードウェアはわが社の5㎝の鉄板で覆われた金庫型の鉄扉の向こうにあるものしか許さぬ!って言われたらそりゃあオンプレ以外にどうすんだよって話ですよ。
そのときに最近クラウドばっかりやってるからって、オンプレミスになったら右往左往するか、って言ったら、そりゃするけど新卒一年目なんかよりずっと役に立つ自信はある。
そもそも右往左往する理由はたいていのばあい、KVMの何番がどのサーバーでしたっけ???とかそんなくだらない理由だったりするわけです。おい誰だ、もう痴呆かって言ったやつ。
あとだいたい夏にiDCに入って「こんなくっそ寒かったっけ!?」ってなって体調崩すとかそういう右往左往です。いやiDCってマジで寒いからね? 夏場に夏服で行ったら普通に遭難しかけるからね??
気温12℃とかそんなとこに半袖で入って一日じいっとキーボード叩いているとか、ただの自殺行為だからね。
普段から入ってりゃあなれるんだけど、クラウド漬けの中でごくたまーーーーーーーーに行くと死にかける(軟弱。
なので、Lambdaもたぶんそういう類のものです。Dockerコンテナだってそうだし、フレームワークだってそうだった。Smartyテンプレートエンジン(まだあるんか? と思って調べたらまだ生きてんのかよw)とかで書かれてるくっそ古いサイトが出てきたって、開発者の方々は一応読めるはずだと思ってる。抽象度とそのレイヤが違う、という話であって、実装方法とかやり方とか開発スタイルとかは思い思いの方法でやればいいじゃん、と思うんですよね。
そもそもServerlessならAWS SAMやamplifyの出番だろうし、データモデルとかORMっぽいことしてくれるとしたらServeless Frameworkのお仕事だろう。やってくれるかどうかは知らない。APIでどうにかなることじゃないからしないだろうけどさ。Lambdaはあくまで部品に過ぎないと思うし、SAMとかならCode CatalystでもVS Codeでも好きな開発環境使えばよいのではなかろーか。そこから初回のSQL文くらいぶん投げればよかろうし、イニシャライズに過ぎないんだからgitに含まれてたって何の問題もない。
え? SQL文が作れない? ORMに頼りすぎだ!w
ただ一つ言えるのは、これらのマイクロサービスを構築するServeless系のフレームワークの何使おうか、という選定において、この方法論の選択基準にモノリシックアプリのフレームワークとくらべてどうだ、という議論を持ち込むのはとてもナンセンスだと思います。
そもそもLaravelとかのフレームワークのほうがインフラから見たらブラックボックス過ぎて気持ち悪いんだけどね…。
ぶっちゃけた話、Dockerを「マイクロサービスの実現」としてアプローチしているならLambdaへのアプローチはただの正当進化でしかない、と思います。
だから、ここのステップアップで困るってことはDockerをVMの延長線上にとらえている場合、ということになるんだよなぁ…。こまったなぁ…。
インフラ的にはVMとDockerはお友達でもなければ進化の軸としても別々の生き物なんだよなぁ。
クジラ見て「海にいるからおさかな!」って言われている感覚に近いんですよね…。似てるけど全然別もの、というか。使い方も活用方法もそもそもの目的も、ほとんどの側面で違いが大きくて、ただ、アプリケーションサイドからみたら大差がないように見えてしまっているだけ、というか。
でもまあ気持ちはわかるよねw 海にいるし。泳いでるし。「うんそうだね、おさかなさんだねー」って返事はするけど、心の中で「哺乳類なんだよおおおおお」ってなるっていうか。
魚もクジラもどっちも食用です。くらいの共通点しかインフラは感じてない、と思います。そして、開発サイドではそこ(食用可)だけを重視しているケースがみられる、というか。
適当に書いたけどそういやDockerのロゴ、クジラだったなw
まずはコンテナで小さく切り分けてPub/SubやRESTでやれる、というものを作るのが先なのかなぁ…。
マイクロサービスを適切に実装している開発サイドって、どんな風にモノリシックとの折り合いつけたのか、聞いてみたい気はしますねw