ferciのIaC(Infrastructure as Code)を振り返る

こんにちは。マネックス・ラボでferciを担当している佐藤です。 ネタに困っていたところ、弊社のHから「新しく作るシステムをCloudFormationでIaCやってみているのだけど意外と大変で、Terraformとどちらが良いか」と話題を振られました。 それをきっかけにferciの初期構築時に残したドキュメントを漁ったり、書き起こしたスクリプトやらをみていると、色々と反省点がたくさん出てきます。 構築してから3年も経つとそんなものなのかな、とも思いますが、その反省点といいますか、今ならこうしてみたい、と言ったことをつらつらと書いてみたいと思います。

f:id:fullstuck_sato:20220301172810j:plain:w320

IaC(Infrastructure as Code)について

ferciでも当たり前のようにIaCでインフラを作って運用しています。ツールはCloudFormationを使っています。 構築当初からTerraformも気にはなっていましたが、公式が出しているツールが一番手堅いだろうと言うことでCloudFormationにしました。 スタックの構成はリソース間の依存関係でかなり苦労したものの、早めに無難なスタックの分離方法にたどり着き、複数人で開発ができる状態を作ることができました。 Terraformについては、システムをリリースした後に移植を試みたものの、tfstateファイルを管理することに神経を使いたくなかったので、諦めました。 結局、構築から3年間、少なくとも本番環境では問題が起きることなく運用できているので、CloudFormationを選んだことは正解だったのかなと思います。 とは言ったものの、CloudFormationはハマりどころが多いので、次に何かインフラを作ることになった時は、tfstateファイルの管理を頑張りつつTerraformにチャレンジしたいところです。

CI/CDパイプラインについて

初期の頃から、とにかくCodeBuildを使う文化を定着させてきました。小さいLambdaのデプロイにも、Codeシリーズを使っています。 作業ミスを減らしたり、Blue/Greenデプロイができるなどのメリットもありますが、記録や承認ができることも大きいと思います。 開発環境で思ったように動いていない時にログを見ると、他の人がデプロイをしていたり。本番環境で、必要に応じて承認のプロセスを挟むこともできます。 記録を残したり承認することは金融機関でシステムを作る上で求められることなので、これも徹底しておいて正解だったのかなと思っています。

スクリプトについて

CloudFormationは便利ではあるものの、書けないリソースも多々あります。わかりやすい例だと、Blue/Greenデプロイで使うデプロイメントグループがそれだと思います。 こうしたリソースはPythonスクリプトで書いたのですが、今見てみると読むのがかなり大変でした。型チェックはあった方がいいですね。TypeScriptの方が非同期処理も書きやすくて良かったと思います。Rust版のSDKが正式に出たら、Rustにしたいですが。

開発環境で事故を起こす

ferciのバックエンドは全て社員で構築し、運用してきたのですが、構築初期に社内から人を集めて量産体制に入った時には、多少の混乱もありました。 CloudFormationでスタックを削除しようとしたところ、リソースがスタック間で循環参照してしまい削除できず、サポートに問い合わせをしてもなかなか解決しないことがありました。 CloudFormationは何かしようとすると待ち時間が長く、開発環境とはいえ、トラブルが起きるとかなり精神を消耗します。 その時はかなり苦労した記憶がありますが、本番環境でもそうした問題が起こりうるということを知れたのは、良いことだったように思います。 かつてNetflixのChaosMonkeyがもてはやされていたように思いますが、本番環境でなくとも開発環境をどんどん壊してトラブルに備えるのは良いように思います。

まとめ

総括して、一番の悩みどころはCloudFormationか、Terraformのどちらを使うか、かなと思います。どちらを選んでも、どこかに大変さが隠れているわけです。 ただ、この悩む原因はおそらくIaCに夢を見すぎていたことにあるように思います。 なんとなくですが、導入事例などを見聞きして、心のどこかに幻想を抱いていたのだと思います。

  • コードとして書いたものをサクサクデプロイできると思っていた
    • 実際はリモートでインフラのリソースを作成したり変更するので、かなり待たされます。作業もそれだけ遅くなります。
  • 記述した通りに差分を埋めてくれると思っていた
    • 日本語圏だけですが、不変のインフラという言葉がありましたけれども、これも幻想ですね。インフラのリソースはどんどん変わっていくので、手元にある通りにはなりません。
  • コマンド一発でインフラが作れると思っていた
    • CloudFormationで顕著ですが、スタックを分け、それぞれで依存しているリソースがある場合には、一度依存するリソースの参照を省いてデプロイした後に、それぞれのスタックに互いのリソースを指定して再度デプロイするようなことが必要になります。また、テンプレートで記述できないリソースはスクリプトでAPIを叩く必要もあります。そうすると、結局デプロイするための手順書のようなものが必要になってきます。

これらは結局のところどこかで妥協しなければならず、そうすると、ツールは正直なところどちらか好きな方を選べば良いのかなと思います。

佐藤 俊介マネックス・ラボ