👨‍💻

インフラとアプリ、同じ脳で回すと何が起きるか知った話

に公開

CDKでインフラを触っていると、deployに数分〜十数分かかることがある。最初は「遅いな」くらいにしか思っていなかった。

でも、ある日気づいた。

この待ち時間、アプリ開発の感覚とまったく違うぞ、と。

Reactを書いているときは、保存すればすぐ画面に反映される。エラーが出ても秒で直せる。「書く→確認→直す」のサイクルが数秒で回る。

一方、CDKは違う。書いて、synthして、deployして、CloudFormationが動いて、5分後に「IAM権限が足りません」と言われる。直して、またdeploy。また5分待つ。

この違いは単なる「速度の差」じゃないな、と思い始めた。

トライアンドエラーが1桁遅いという現実

アプリ開発とインフラ開発で、1回の試行にかかる時間を比べてみる。

アプリ開発の場合

コードを書く
→ 保存
→ Hot Reload
→ 画面確認
→ エラーなら修正

所要時間:数秒〜数十秒

インフラ開発(CDK)の場合

コードを書く
→ cdk synth(テンプレート生成)
→ cdk deploy(AWS APIコール開始)
→ CloudFormationがリソースを作成
→ VPC、ALB、RDS...それぞれ数分かかる
→ 途中で失敗したらROLLBACK
→ ロールバックも数分待つ
→ 原因調査
→ 修正して最初に戻る

所要時間:5〜30分

1桁どころか、場合によっては2桁違う。

アプリ開発の感覚で「とりあえず試してみよう」をインフラでやると、1日があっという間に終わる。午前中に3回しかdeployできなかった、みたいなことが普通に起きる。

エラーが「遅れて返ってくる」問題

アプリ開発では、エラーは即座に返ってくる。コードを書いた瞬間にエディタが赤線を引いてくれるし、実行したらすぐに例外が飛んでくる。

インフラは違う。

deployを実行して、5分待って、やっと「依存関係の順序が間違っています」と言われる。「え、それ最初に教えてよ」と思っても後の祭りだ。

Transit Gateway VPC Attachmentをデプロイしようとしたときの話をしよう。

コードを書いて、deployして、待つこと数分。エラーで止まった。なんでだろうと調べてみたら、Attachmentには「承認」というステップがあって、CDKはそれを待てないからタイムアウトする、と。

削除しようとしてもスタックが途中で止まって、DELETE_FAILEDの文字を見ながら手動でリソースを消す羽目になった。

この「フィードバックの遅延」は、思っている以上にストレスが溜まる。そして、思考のリズムが完全に変わる。

実行環境が手元にないという制約

Reactのコードはローカルで動く。Node.jsのスクリプトもローカルで動く。ローカルで確認してから本番に反映する、という流れが当たり前になっている。

でもインフラは?

VPCはローカルに作れない。ALBもRDSもEKSも、全部AWS上にしか存在できない。LocalStackのようなエミュレータはあるけど、完全な再現は無理だ。

ローカルで確認できないから、「とりあえず本番(または検証環境)でやってみる」しかない。試行回数を増やしたくても、物理的に増やせない。

この制約が、インフラエンジニアの思考パターンを形作っている。

2つの思考パターン

アプリエンジニアの思考パターンは、こうだと思う。

書いて → 動かして → 直す

フィードバックが速いから、まず手を動かす。動かしながら考える。間違っていたらすぐ直す。このサイクルを高速に回すことで、正解にたどり着く。

一方、インフラエンジニアの思考パターンは違う。

考えて → 想像して → 一発で当てに行く

フィードバックが遅いから、手を動かす前に考える。「このリソースを作ると、どういう状態になるか」を頭の中でシミュレーションする。できるだけ一発で正解を出す。試行回数を減らす方向に最適化する。

どちらが優れているという話ではない。環境の制約に適応した結果、こうなっているだけだ。

同じ人間が両方やると何が起きるか

問題は、この2つの思考パターンを同じ日に、しかも短い間隔で切り替えようとしたときに起きる。

午前中にCDKでインフラを触っていて、deployを待っている間に「ちょっとReactのバグ直しておこう」と思ってアプリのコードを開く。

数分でバグを直して、「あ、deploy終わったかな」とターミナルを見ると、まだ動いている。じゃあもう少しアプリを進めよう。

気づいたらアプリの作業に没頭していて、インフラのdeployが成功したのか失敗したのかわからなくなっている。確認したら失敗していて、また最初からやり直し。

これを繰り返していると、どっちも中途半端になる。インフラは進まないし、アプリも集中できない。脳が「スワップ」を起こしている状態だ。

なぜコンテキストスイッチが高くつくのか

単にタスクを切り替えるだけなら、そこまで問題ないはずだ。でも、インフラとアプリの切り替えは特別にコストが高い。

理由は、思考パターンそのものを切り替えないといけないから。

アプリモードの脳は「すぐ試す」方向に最適化されている。だから、インフラでも「とりあえずdeployしてみよう」という判断をしてしまう。結果、5分待った後に失敗して、また5分待つ。

インフラモードの脳は「一発で当てる」方向に最適化されている。だから、アプリでも設計を詰めてから書こうとしてしまう。結果、数秒で試せることに何分もかけてしまう。

切り替えた直後は、前のモードの思考が残っている。これがバグを生む。

インフラエンジニアの「待ち時間」との付き合い方

インフラエンジニアは、この待ち時間とどう付き合っているのか。

聞いてみると、「待ち時間を前提にタスクを並行化する」のが上手い人が多い。

deployを実行したら、終わるまで待たない。別のPRをレビューしたり、ドキュメントを書いたり、次のタスクの設計を考えたりする。「今deploy待ちだから、次に何やるか」を常に持っている。

待ち時間は「無駄な時間」ではなく「別タスクの時間」として組み込まれている。

この発想の転換ができるかどうかで、インフラ作業のストレス度合いがかなり変わる。

兼任するなら、意図的に分ける

両方やらないといけない状況は、個人開発では珍しくない。そういうときは、意図的にモードを分けるのが良いと思う。

日を分けるやり方。

月曜はインフラ、火曜はアプリ、水曜はインフラ、という具合に。その日は片方しかやらない、と決めてしまう。

時間帯で分けるやり方。

午前中にインフラを仕掛けておいて、午後はアプリに集中する。deploy待ちの時間は、ドキュメントや設計など「どちらでもない作業」を挟む。

どちらにしても、「今自分はどっちのモードか」を意識することが大事だ。無意識に切り替えると、前のモードの思考が残ってバグになる。

事前検証という投資

インフラの試行回数を増やせないなら、1回の試行の成功率を上げるしかない。

deployする前にできることは全部やる、というのが鉄則になる。

# 型チェック
npx tsc --noEmit

# Lint
npm run lint

# synthでテンプレート生成
cdk synth

# diffで差分確認
cdk diff

ここまでやってからdeploy。「とりあえずdeploy」は禁止。

この事前検証に時間をかけることで、deploy後に「5分待ってエラー」という最悪のパターンを減らせる。

属人化という見えないリスク

もう一つ、兼任には大きなリスクがある。属人化だ。

インフラもアプリも同じ人がやっていると、その人がいなくなったときに何も回らなくなる。特にインフラは「経験値がものを言う世界」なので、暗黙知が溜まりやすい。

「このスタックはこの順番でdeployしないと壊れる」「このリソースは手動で承認が必要」「このエラーはIAMポリシーをこう直せば通る」

こういった知識が一人の頭の中にしかないと、その人が休んだり辞めたりしたときに詰む。

しかも、兼任している人は忙しい。ドキュメントを書く時間なんてない。結果、属人化が加速する。

マネージャーの方へ

ここまで読んでいただいた方の中には、チームのマネジメントをしている方もいるかもしれない。

お願いがある。

インフラとアプリを同一人物に任せないでほしい。

「Aさんは両方できるから」「人が足りないから」という理由で一人に任せると、短期的にはコストが下がったように見える。でも長期的には、

  • その人が疲弊する
  • どちらかの品質が落ちる
  • 属人化が進む
  • その人がいなくなったとき、誰も引き継げない

というリスクを抱えることになる。

多少コストが上がっても、インフラとアプリは別の人に任せたほうがいい。あるいは、明確に役割を分けて、同時には担当させない。

「両方できる人」は貴重だ。だからこそ、その人を潰さないでほしい。思考モードの切り替えは、見えないところで大きなコストを払っている。

将来的なリスクまで含めて考えれば、分業したほうが安く上がる。間違いなく。

学びと展望

インフラとアプリ、両方の視点を持っている人は強い。それは間違いない。

ただ、思考パターンが違うということを理解せずに両方やろうとすると、どちらも中途半端になる。コンテキストスイッチのコストは、想像以上に高い。

個人開発でどうしても両方やるなら、意図的にモードを分ける。切り替えの回数を減らす。前のモードの思考が残らないように、明確な区切りを作る。

組織でやるなら、分業を検討してほしい。

インフラは「速く手を動かす仕事」ではなく「待ちを前提に設計する仕事」。この認識があるだけで、見え方が変わるはずだ。

Discussion