Infrastructure as Codeとの上手な付き合い方
2021/09/17
2021/09/17
はじめまして、アクセンチュアの仲村です。クラウド・ダイアリーズでは本記事が初投稿となります。
皆さん、CloudFormationやTerraformをはじめとするIaC(Infrastructure as Code)は活用されてますでしょうか。近年ではIaCを活用したインフラ構築はもはや当たり前のことになってきており、活用されている方も多いと思います。
IaCを活用すればインフラ構築の手間と人為的なミスを減らすことができ、非常に便利なため、私も業務の中でIaCを活用したインフラ構築を行っておりますが、以下のような課題に困ることがありました。
課題: ほとんどのコードはすぐに書けたのに、一部のコンポーネント・特殊な要件への対応に膨大な手間がかかっていて、全然終わらない。
皆さんもこんなお悩みをお持ちではないでしょうか。本記事ではAWSにおける環境構築を対象に、この悩みに対する1つの解決策を説明したいと思います。もちろんチームのスキルセットや規模、システムの要件、運用方式などに応じて正解は異なりますが、1つの考え方としてご覧いただければ幸いです。
本記事でお伝えしたいことは非常にシンプルで、
ということです。
課題をもう一度見てみましょう。
課題(再掲): ほとんどのコードはすぐに書けたのに、一部のコンポーネント・特殊な要件への対応に膨大な手間がかかっていて、全然終わらない。
「一部のコンポーネント・特殊な要件への対応に膨大な手間がかかる」という点について、いくつか具体例を挙げてみます。
過去の例になってしまいますが、ECSのBlue/Greenデプロイは2020年の5月までCloudFormationでサポートされていませんでした。サポート前にCloudFormationで対応するには、カスタムリソース機能を用いる必要がありました。
カスタムリソースはカスタマイズ性が高く便利な機能ですが、通常のCloudFormationテンプレートとは記載方法が大きく異なり、カスタムリソースを作成するための特別な学習が必要になります。さらに、コードも難しいものになりやすく、可読性や保守性も落ちます。
そもそも、環境差異は極力無くすべきですが、コスト観点などの事情から大小様々な環境差異が生まれることもあると思います。
インスタンスサイズが異なる程度の差異であれば、IaCで変数を使えば簡単に対応することができます。しかし、例えば「コスト節約のために本番環境以外の環境ではRDSを共有させ、本番環境のみ独立したRDSを持たせる」など、環境差異が複雑なものになると、IaC上の変数や条件分岐が増え、フォルダ構造やコードが複雑となり、可読性が落ちてしまいがちです。またフォルダ構造やコードが複雑になることで、理解を誤り、予期しない挙動から将来的な障害にも繋がります。
IaCを用いてすべてのインフラリソースをコードで管理するということは、とても魅力的ですが、前述の直接サポートされていないリソースや複雑な環境差異などの難しいケースまでIaCで対応しようとすると、かえってインフラ構築が大変になる場合があります。しかも苦しみながら何とか書ききったコードの場合、書いた直後の本人には理解できるものの、将来の自分や別の運用メンバーには理解が難しいものになりがちです。そうなると、せっかくコード化したにも関わらず、作成したコードが運用で全く活かされないことになってしまいます。
1つの解決策として、IaCに過度にこだわることをやめ、一部のリソースはCLIや手作業で作成し、IaCと上手く組み合わせる方針にした方が楽になることもあります。インフラ構築の手間や人為的なミスを減らすというIaCのそもそもの目的に立ち返り、その目的に見合った最適な方法を選択するべきです。
また、時間が経てば、CloudFormationやTerraformのサポート範囲が広がったり、機能が追加されたりすることもあります。いったんCLIや手作業で対応しておいて、後でIaC化していくことも有効な戦略になると思います。
当然ながらCLIや手作業を組み合わせて対応する場合、どんな手順でインフラ構築ができるのか、なぜ部分的にCLIや手作業を組み合わせて対応しているのか、ということをドキュメントで残しておく必要があります。もちろんIaCのみで対応する場合にもドキュメントは必要ですし、無理にIaC化した場合には複雑なコードの説明をするためにかえってたくさんのドキュメントが必要になると思います。
非常にシンプルなことを長く説明してきましたが、今回の課題はIaC化にこだわりすぎて意外とはまってしまいがちな落とし穴の1つだと思っています。今回は言及していませんが、DRY原則(Don’t Repeat Yourself: 重複した記述を避けること)を重視しすぎて、IaCの記述が難解になってしまうというのも同様の問題と考えています。
IaC化を進めるうえでは、そもそもの目的に立ち返って対応を考えていくことが重要です。本記事を読んでくださった皆さまがIaCを上手く活用するための一助となれば幸いです。