はじめに
AWS Copilot CLIは、インフラ構成について深く考えずに済む、非常に強力なツールでした。
先日公開された社内ブログ記事(宣言的記述とメンタルモデル ─ AWS Copilot CLI のサポート終了に寄せて)でも触れられていましたが、Copilotの最大の価値は「何がベストプラクティスかという判断を肩代わりしてくれる」ことにありました。社内で広く使われていたのもこの明確な恩恵があったからです。
今回のAWS CDKへの移行の直接のきっかけは、全社的に利用していたこのCopilotがサポート終了を迎えることになったためです。
ただ、運用する中ですでにツールとのミスマッチを感じ始めていました。Copilotの想定から外れた要件が出るたびに追加のCloudFormation(Addon)で対応する必要があり、かえって構成が複雑化する場面が出てきていたのです。
CDKへの移行は、サポート終了という避けられないイベントを機に、「今の自分たちの要件に合わせて、インフラ設計の主導権を握ろう」と前向きに舵を切った結果です。
本記事では、Copilotの「判断の肩代わり」がもたらした具体的な運用課題と、CDKへの移行によって私たちのインフラ管理がどう変わったのかを振り返ります。
📝 目次
1. 「判断の肩代わり」がもたらした運用上の課題
Copilotのmanifestでは、例えば type: Load Balanced Web Service のような特定の型を指定するだけで、VPC・ALB・ECS・Auto Scalingなどをまとめて定義できました。人間のメンタルモデルに近い抽象度で簡潔に記述できることこそ、Copilot最大の強みでした。
ただ、この「まとめて定義できる」ことの裏を返せば、「細かい部分はすべてCopilotが決定している」ということです。実際に私たちが運用していく中で、壁となったのは以下のような点でした。
1.1. 構成の制約と、記述パラダイムの断片化
Copilotの用意する「型」は強力ですが、そこから一歩踏み込んで独自の最適化を行おうとした途端に、記述が複雑化するもどかしさがありました。
manifestの標準機能では表現しきれないセキュリティグループの詳細設定やRoute53のドメイン設定などを「Addon(CloudFormation)」として別途記述して組み合わせる必要がありました。
このmanifestとCloudFormationという2つの異なる記述パラダイムを行き来するスイッチングコストやコードの断片化は、運用規模が広がるにつれて小さくないストレスになっていきました。
1.2. 抽象化の裏にある挙動の把握
Copilotの高い抽象度は、manifestの設定変更が裏側でどのAWSリソースにどう影響するかをドキュメントから事前に読み取りにくくするという側面を持っています。「この一行を変えたら何が変わるのか」をCopilotのドキュメントから把握しようとしても、manifest設定とCloudFormation出力の対応は網羅的に説明されていません。 結局はGitHub Issueを調べたり、実際にデプロイしてコンソールで確認する、というトライ&エラーのサイクルに頼るしかありませんでした。
最終的にCloudFormationのdiffで変更内容を確認するのが正しいアプローチでその点ではCDKも同じです。ただ、CDKはドキュメントが充実しており、設定の意味や出力を事前に把握できる場面がほとんどです。 特にL1コンストラクトはTypeScriptとCloudFormationリソースの対応が直接的なため、デプロイ前から変更結果を予測しやすく、トライ&エラーのサイクルが大きく減りました。
1.3. アプリとインフラの密結合(インフラリポジトリの独立)
現在の関わっているシステムでは、バックエンドはECSで、フロントエンドはS3+CloudFrontで独立してデプロイする構成を採用しています。 これはAWSが公式のPrescriptive Guidanceでも推奨しているSPAのデプロイパターンです。 フロントエンドとバックエンドをデプロイ単位として分離することで、それぞれのリリースサイクルを独立させ、互いの変更に影響されずにデプロイできます。
このアーキテクチャでは、インフラの管理対象がバックエンド(ECS)とフロントエンド(S3+CloudFront)の両方にまたがります。 そのため、アプリのコードとは完全に切り離されたインフラ専用リポジトリで一元管理したいという要件が自然に生まれました。
AWS Copilotは、copilot/ ディレクトリをアプリケーションリポジトリ内に配置し、アプリと同居させて管理することが基本の設計思想です。
copilot/ をどのリポジトリに置くかはチームが選択できますが、どこに置いたとしても「インフラ定義がいずれかのアプリリポジトリ内に存在する」という状態は避けられません。
私たちが目指していた「すべてのアプリリポジトリから独立したインフラ専用リポジトリ」という構成は、Copilotの設計思想の外にありました。
2. AWS CDKに移行して変わったこと
CDKへの移行によって、記述のパラダイムが統一され、インフラ管理の見通しが大きく改善されました。具体的には、以下の4つの変化が挙げられます。
- 自由な構成への再設計 — CDKには「L1〜L3コンストラクト」という抽象度の異なる概念があり、これらを単一のコード内で自由に組み合わせられます。特に効いたのが、L3コンストラクトである
QueueProcessingFargateServiceの導入です。SQSのメッセージ量に応じたオートスケーリングを含むワーカーの構成全体を、数行のコードで表現できるようになりました。 - プログラミング言語を活かしたインフラ記述 — CDKはTypeScriptをはじめ複数の言語をサポートしています。私たちはTypeScriptを選択しましたが、ifやループといった制御構文が使えることに加え、AWSリソースの生成ロジックそのものをTypeScriptの型システムで保護できることが大きな利点です。IDEの補完はCloudFormationのスキーマ定義でも一定程度得られますが、CDK+TypeScriptではリソースを生成するコードそのものが型安全になるため、複雑な構成も見通しよく管理できるようになりました。
- コードでの完全な完結 — Copilotでmanifestの表現力を超えるような設定が必要になると、CloudFormation(Addon)という別のパラダイムへの切り替えが発生し、その学習や記述のコストがかかっていました。CDKではL1コンストラクトを使えばCloudFormationと同等の表現力をCDKのコードのまま扱えるため、パラダイムを切り替えることなく、ほぼあらゆる設定を同じコードベース内で完結できます。
- インフラリポジトリの独立 — マルチリポジトリの運用に合わせて、インフラを専用の独立したリポジトリへ完全に分離し、一元管理できるようになりました。これにより、アプリケーションコードに一切ノイズを混ぜることなく、アプリとインフラのライフサイクルをきれいに分離できました。
4つの変化に共通するのは、インフラの設計判断を「Copilotが想定する正解」ではなく「自分たちの要件」を起点に考えられるようになったことです。制約に沿った設計から、意図を直接コードに落とす設計へ——この転換が、日々の運用感覚を大きく変えました。
3. ベストプラクティスは誰のためのものか
冒頭で紹介した社内記事にもあるように、Copilotの高い抽象度は「AWSを深く知らなくてもベストプラクティスな構成で動かせる」という素晴らしい価値を生み出していました。
しかしこの移行を通じて改めて感じたのは、「AWSとしてのベストプラクティス(=Copilotのデフォルト)」が、必ずしも「私たちにとってのベストプラクティス」とは限らないということです。
私たちには私たちの要件があり、コスト感があり、技術スタックがあります。今回の移行でも、「どのリソースをどの粒度で管理するか」「ワーカーをどうスケールさせるか」といった問いをチームで議論し、Copilotのデフォルトとは異なる選択をした箇所が複数ありました。 インフラをアプリと完全に分離したリポジトリで管理したいという方針も、バックエンドとフロントエンドを独立したデプロイ単位として扱いたいという設計も、Copilotが想定する標準的な「正解」の外側にあったのです。
「判断の肩代わり」は、「自分たちの要件に合わせた判断をする余地が狭まる」ということでもあります。AWSの知識を設計にしっかり活かしながら、インフラを自分たちでコントロールしていきたいチームには、間違いなくCDKがフィットするはずです。
4. おわりに
Copilotのサポート終了は、単なるツールの移行作業ではなく、「何をツールに任せ、何を自分たちで判断するか」を根本から問い直す貴重なきっかけになりました。
Copilotが肩代わりしてくれていたインフラ設計の判断を、改めて自分たちで一つひとつ引き受けてみると、そこには、これまで諦めていた設計の選択肢が普通に取れる余地が広がっていました。
万人に共通する「完璧なベストプラクティス」はありません。プロダクトの成長やチームの状況によって、正解は変わり続けます。その時々の要件ときちんと向き合って、自分たちに合った選択をしていく——そういう姿勢が、長い目で見たシステムの健全性につながるのではないかと考えています。
今回のCDK移行を通して得た最大の収穫は、新しいインフラ構成そのもの以上に、「自分たちのベストプラクティスは自分たちで選べる」という確かな感覚です。
ツールやフレームワークの選択においても、同じことが言えるはずです。もし今、「世間的なベストプラクティス」と「自分たちの要件」の間に窮屈さを感じているなら、一度立ち止まって「これは誰のためのベストプラクティスなのか」を問い直してみてはいかがでしょうか。