2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
全AWSアカウント×全CDKアプリでLegacyテンプレートをMigrationした話 (全1記事)
リンクをコピー
記事をブックマーク
大越雄太氏(以下、大越):「全AWSアカウント×全CDKアプリでLegacyテンプレートをMigrationした話」をします。よろしくお願いします。今回は5つの章に分けて話を進めます。では「ことの始まり」からお話ししていきたいと思います。
知らない方が大半だと思いますが、実は私たちjustInCase(株式会社justInCaseTechnologies)は、CDK v1発表前からキャッチアップをしており、バージョン0.33から利用を開始している超ヘビーユーザーです。
当時の「Slack」のスクリーンショットをスライドに貼りましたが、これだけではわからないと思うので、CDKの歴史と並べてみました。まず、2018年9月にバージョン0.8のファーストパブリックリリースが公開されました。その後、2019年7月にバージョン1が、2019年11月にバージョン1.18のCDK for Javaが一般公開されました。
それに対して私たちjustInCaseは、2019年2月からCDKのキャッチアップを開始しています。さらに4ヶ月後の2019年6月には、CDK v0.33をKotlinから動かすことに成功しました。ここからjustInCase内でのCDK利用が活発化します。
なぜそこまでCDKをKotlinで動かすことにこだわるのかというと、当時のjustInCaseは、Kotlinユーザーが大半を占めており、KotlinでCDKを書くために「AWS-CDK-Kotlin-DSL」を独自で開発するほどでした。これはawesome-cdkのLanguage Supportの欄の一番上に載るほど、有名なライブラリに育ちました。
大越:そんなヘビーな使い方をしている私たちですが、CDK v1に対してはみなさんと同じつらさを強く感じていました。ライブラリが個別なので、CDKリポジトリが大量にあるとバージョンアップが大変だったり、Constructの抽象度が低くて新規開発のたびに同じコードを書く羽目になったり。そんなつらさを感じていたjustInCaseのエンジニアだからこそ、CDK v2の発表を知った時、世界で一番幸せを感じていたのかもしれません。
そんな幸せムードの中、とある古参メンバーが「CDK v2も出てきたことだし、当社でもアップグレードを進めていきましょう!」と提案し、「機能開発のついでに、v2化をしてみました」というプルリクを出してくれました。このプルリクは、問題なくリリースが完了しました。しかし翌日から、それ以外のCDKリポジトリのデプロイが失敗するようになってしまいました。
さて、この原因はいったいなんだったのでしょうか? それは、v2のためだけにbootstrapすると、なにもしていないv1のデプロイはエラーになるからでした。
大越:CDKを利用するためには、cdk bootstrapコマンドを使い、CDKToolkitというスタックを利用するリージョンにデプロイする必要があります。そのCDKToolkitのテンプレートには、大きく分けてModernテンプレートとLegacyテンプレートの2種類が存在します。もともとはLegacyテンプレートのみでしたが、のちにModernテンプレートが登場しました。現在はどちらも生成・利用が可能です。
今回、この2つの違いについては触れませんが、詳しく知りたい方はスライドの「クラスメソッド」の記事を読んでもらえればと思います。
さらに、CDK v1の初期はLegacyテンプレートしか利用できないので、justInCaseではLegacyテンプレートでのデプロイが行われていました。なお、CDK v1のデフォルト設定では、Modernテンプレートを利用したデプロイのサポートはしていません。
またCDK v2では、Legacyテンプレートによるデプロイのサポートもされていませんでした。なので、CDK v2を利用するためにはModernテンプレートを利用する必要があります。これらの理由から、v2のためにbootstrapするだけではなくv1のModern化対応が必要なことに気がつくことができませんでした。これが(エラーの)主な原因です。
大越:しかし、AWSがそんな仕様を認めるのだろうか? 僕は気になって調べてみました。結論から言うと、LegacyとModernのCDKアプリを共存させることは可能です。共存させる方法について。cdk deployの前にModernとLegacyのCDKToolkitを作成しておき、デプロイ時にどのCDKToolkitを利用するのかをオプションで指定する必要があります。
共存した場合のメリット・デメリットとしては、既存のv1をほぼそのまま使えるというメリットがあります。ただし、リージョンごとにLegacyとModernの2つのCDKToolkitをデプロイする必要があるほか、cdk deployの時、オプションでわざわざどのCDKToolkitを使うのかを指定しなければならなくなってしまいます。
大越:それに対し、完全移行のメリット・デメリットの場合。まずデメリットですが、短期的な作業が少し大変です。利用するAWSアカウントとリージョンすべての環境でCDKToolkitをmodernへ変更する必要があります。また、CDK v1リポジトリのすべてでmodernフラグを設定する必要があります。
しかし、この2つに関しては一度やってしまえば終わりなので、長期的な作業はほぼありません。AWSアカウント作成時のCDKToolkitのキッティングに関しても楽になるし、エンジニアがcdk deployする時に余計なオプションを付けないで済むというメリットもあります。また、誤ってv1が使われるのを防ぐことでv2への移行を後押しできることもメリットです。
ちなみにv1は、2022年6月にメンテナンスモードに移行します。メンテナンスモードに移行してしまうとL2以上のConstructがアップデートされなくなるようなので、そこは注意してもらいたいと思います。
これらの理由や、社内からのアップグレードに対する熱い希望もあり、全AWS環境の完全移行の覚悟を決めました。
大越:「マイグレーションを通して学んだTips」について。話したいTipsは2つあります。cloudformation_includeの便利さについてと、bootstrapする時のテンプレートのバージョンについてです。まずは、cloudformation_includeの便利さについてお話しします。
justInCaseのKotlin CDKでは、Modernテンプレートに対応していないバージョン1.20からバージョン1.64を利用しています。この問題を解消するためには、Kotlin CDKをなんとかアップグレードするか、TypeScriptへの移行を行うかという2択で、とても悩みました。
マイグレーション時に残っていたKotlin CDKのリポジトリは全部で4つで、リポジトリあたり500行から1,000行ぐらいのKotlinのコードがありました。これらKotlin CDKのアップグレードは1.63で止まっているし、それらすべてのKotlinコードをTypeScriptへ書き換えるだけでも何百時間もかかってしまう。そんな悩みを抱えながら、数日間思考を巡るに巡らせ、結局CDKは「CloudFormation」のテンプレートを出力して、スタックをデプロイしているだけだということに気がつきました。
そして、cloudformation_includeで管理する方法を思いつきました。CloudFormationモジュールを使えば、既存スタックのCloudFormationテンプレートをファイルとして管理できる。スライドのソースコードのようにテンプレートファイルとして読み込めば、CDK側で利用することが可能です。これについては、v1、v2のどちらにもあったので実行することは可能だと思います。
また、CloudFormationを利用しているリポジトリや、エンジニアが行方不明になり管理できなくなってしまったCDKリポジトリなど、そういったものが残念ながらいくつかあると思います。そのような場合でもcloudformation_includeを使えば、簡単にダウンタイムなしで移行することができます。
また、環境ごとにテンプレートやリソースが異なっていることが必ずあると思います。例えばDBのサイズやドメインですね。そのような場合は、商用環境のテンプレートをもとに各環境向けの定義で上書きしてデプロイすることができます。これを使うことで、扱いの難しいCloudFormationの拡張構文やKotlinをイチから学ぶことなく、とてもスムーズにTypeScriptに移行できました。
大越:2つ目は、bootstrapする時のテンプレートバージョンについてです。実は、bootstrapを実行するCDK CLIのバージョンによって展開されるModernテンプレートの内容が異なります。v2を使っていれば基本的に大丈夫だと思いますが、v1を使っている時はかなり注意が必要です。
v2で生成したCloudFormationテンプレートには、Modernテンプレートのバージョンが6以上でないとエラーになるルールが追加されています。(スライドを指して)こちらが自動的に追加されるルールです。これについては、実際に手元でdiffコマンドを実行するとどのようなルールが追加されるのかがわかるので、一度実行してみるといいと思います。
これらの理由から、bootstrapする場合はCDK CLIのバージョンが最新かどうかを確認してから実行することで、この問題を事前に回避できます。以上がbootstrapする時のテンプレートバージョンについてでした。
大越:マイグレーションを終えて。CDKを使う人にとっては、justInCaseは最高の環境を作ることができたと思います。bootstrapも最新のバージョンで、すべてのAWSアカウントで実施済みです。これからjustInCaseに入る人は、LegacyやModernを気にせず開発に集中することができます。
この話を聞いてCDKをぜひ業務で使ってみたいという方に向けた情報があるようなので、小笠原さんにバトンタッチしたいと思います。
小笠原寛明氏(以下、小笠原):お約束の宣伝タイムです。もともとv1には10個以上のリポジトリがありましたが、順次v2へのアップデートを進めていて、ここで話していない知見もけっこうあります。
こういうL3 Constructが使えるとか、こういう「Construct Hub」を使うと便利だとか、そういったものがあるので、それらを内側から知りたいという方は、うちの会社に来てもらえればたくさんお話しできると思います。
「カジュアル面談とか大変」という人のために、たくさん情報発信をしています。技術ブログのリンクをTwitterに貼りますが、毎週金曜日の夜に「クラウドのニュース、読むぜ」というのをTwitterスペースをやっているので、そちらに来てもらってたくさんお話しできるとうれしいです。CDKを使う人、たくさん話しましょう。よろしくお願いします。
大越:お願いします。発表は以上です。ありがとうございました。
小笠原:ありがとうございました。
吉田真吾氏(以下、吉田):ありがとうございました。すばらしい創意工夫ですね。
小笠原:ありがとうございます。
大越:ありがとうございます。
吉田:できなかったらヤバかったみたいなことがいくつかあったと思うのですが、なんとか載せきれたという感じですね。今アカウントには、LegacyテンプレートとModernテンプレートのCDKToolスタックがそれぞれ、いろいろなリージョンに載っているという感じですか。
大越:いえ、Legacyテンプレートを使うアプリはすべてModernテンプレートを使うかたちに移行したので、うちの場合はLegacyテンプレートは気にしなくて大丈夫です。
吉田:了解です。
小笠原:これ、大変だったんですよ。最初のリポジトリが10個ぐらいあって、全部にフラグを立てたうえで、対象のリージョンがまた10アカウント以上、3リージョン以上あって、それら1個1個に対して全部v2でbootstrapするというのを真面目にやったんですよ。
大越:そうですね。
吉田:大越さん、大変でしたね。
大越:大変でした。
吉田:新居田さん、質問は来ていますか?
新居田晃史氏(以下、新居田):はい。「現在もCDKはKotlinで作成しているのでしょうか?」。いかがでしょうか。
小笠原:お答えすると、やめました。というのは、もうCDK v2の進化を見てL2、L3のConstructもたくさん出てくるので、これはこっちに乗っかったほうがいいだろうということで全部TypeScriptに移りました。さらに進んだこともやっています。例えばアプリケーションのフロントエンド、バックエンドとインフラ全部をTypeScriptでモノレポで管理するようなこともやっていて、なかなかいいです。
なので、TypeScriptを持ってきたのは正解だったと思います。ついでに語ると、JAWSの話なのにアレですが、CIに「GitHub Actions」を使うことが今増えていると思うんです。一方で「ECS」などのデプロイはコアの部分だから、AWSで、「CodePipeline」でやりたいというケースもあると思っています。そういう場合、インフラに修正を加えようとすると、GitHub ActionsとAWS側の修正を同時に加えなきゃいけないんです。
というわけで、リポジトリのライフサイクルとインフラのライフサイクルが一緒になってしまうので、まとめたほうがいいという実感があります。
吉田:まとめたうえで、例えばECS側に変更が加わった時は、GitHub Actionsはフロントで使っている。
小笠原:実は全部で使っているんですよ。
吉田:全部で使っているんですか?
小笠原:フロントのデプロイとバックエンドのデプロイの両方で使っています。
吉田:じゃあ、すべてのプッシュのイベントに関してGitHub Actionsが走るかたちになるんですね。
小笠原:もちろん変更されているワークスペースがどこかというのは見ますが、一応走っています。そのGitHub Actions側でコンテナのイメージを固めて「ECR」にプッシュして、ECRのプッシュをトリガーにしてCodePipelineが走るみたいな。
吉田:なるほど。
小笠原:全部CodePipelineでやったらいいじゃんと思われるかもしれません。理由が2つあって、1つはGitHubのリポジトリごとのWebhookの個数の上限が20までということ。もう1つは、1個のコンテナイメージを複数の環境にデプロイする場合に、それら全部でコンテナイメージを管理するのか、それとも1ヶ所からプッシュしてしまうのか、どちらのほうが効率がいいのかということですね。
吉田:今のコンテナのイメージに関しては、基本的には1ヶ所に上げて、1ヶ所から複数のリージョンにばらまいているんですか?
小笠原:1ヶ所に上げるまではやっていません。今は1ヶ所でビルドして、それを各箇所にプッシュしていますが、将来的には1ヶ所にプッシュして、クロスアカウントでECRを読みにいくようにしたいと思います。
吉田:わかりました。質問は以上でしょうか。
新居田:そうですね。
吉田:追加があれば、Twitterで引き続き回答してもらいたいと思います。justInCaseの小笠原さんと大越さん、ありがとうございました。
大越:ありがとうございました。
新居田:ありがとうございました。
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05