🙄

何を狙ってInfrastructure as Code化してますか?

2025/01/17に公開

これまでいろいろなプラットフォームを構築してきたのですが、オンプレミスで仮想化・コンテナ化するにしても、クラウド上で構築するにしても、現在のトレンドはコード化でしょう。一般的にはInfrastructure as Code(以下、IaC)と呼ばれています。「IaC化しています」というとちょっとかっこいいですしね。ただ、重要なのは何を狙ってコード化しているのか?、あなたのコンセプトは何ですか?という部分だと思います。

私のインフラ構築のキャリアは長いですが、2017年から2024年までAWSの環境を構築してきました。IaC化を推し進めてきたのですが、あらためて振り返ると目的は2パターンがあると思います。

  • 構築を楽にすることを狙っている
  • 構築でミスを無くすことを狙っている

もちろんクロスオーバーする部分はありますが、2つの狙いでやることが大きく変わってきます。今日はその話を解説してみようと思います。(というのは後輩からIaC化の相談を受けて、そもそも何を狙っているの?と聞いて解説したので、それを文字化してみます)

楽をしたいパターン

いきなりインフラの話をする前に、例としてプログラミングの話をしました。プログラマーが楽をするために、以前書いたコードをコピペすることはよくあると思います。私も昔はいろいろコーディングしましたが、例えばバッチ処理を書いたシェルプログラムがあったとします。別のバッチ処理が必要になり、そのシェルプログラムをコピーして、必要に応じて変更したり、処理を加えたりすることはあると思います(コピペした時に、不要な処理を消し忘れたり、不要なインクルードをそのままにして先輩に怒られた苦い思い出もあります)。

楽をしたいパターンのIaC化はまさにこのようなやり方で、一度作ったコードを再利用することで、似たような処理を簡単に作ることができます。特にインフラ構築の場合、似たような作業が何度も登場するので、再利用の効果は絶大です。一度作ったコード(AWSならCloudFormationのYAMLファイル)をGitに保存しておくことで、簡単にインスタンス追加もできるようになります。また、このようなIaC化は構築したコードと、その作業ログをセットで残すこともできるので、後で何をやったかのトレーサビリティも向上します。仕事を楽にしつつ、後から追うこともできるのでいいことづくめな気もします。

ミスを無くしたいパターン

さて、ここまで読むとIaC化ってまさしく上記のようなパターンなのでは?と思われる方もいらっしゃると思います。ただ、私が目指したAWS構築はこれとは別の狙いを持って行ってきました。タイトル通り、ミスをゼロにしたいことが目的です。クラウド構築の場合、オンプレミスと異なり、ミスしないことが重要です。インターネットに簡単に接続できるので、ミスがそのままセキュリティーホールになります。つまり、構築によるミスをゼロにすることが求められます。

では、どうやってミスをゼロにするかなんですが、詳しくはこちらの本に書きました。別に宣伝したいわけではないので、概要はこのブログに書いてしまいます。
https://direct.gihyo.jp/view/item/000000000630?category_page_id=ct196

先ほど、AWSならCloudFormationのYAMLファイルで構築すると書きましたが、YAMLファイルの中にも可変値と固定値があります。例えば、EC2のインスタンスタイプは可変値になります。前回構築したインスタンスタイプが「m8g.medium」として、今回はもっと大きなサーバーが必要であれば、インスタンスタイプは「m8g.xlarge」を選択するかもしれません。そのように変更される部分が可変値ということになります。
https://aws.amazon.com/jp/ec2/instance-types/

ミスを無くすには固定値と可変値を分けて、固定値が変わらないように管理する必要があります。そうすることで、構築時のレビュー負荷やテスト負荷を削減できます。私はこの固定値と可変値を分けたYAMLファイルをテンプレート化して再利用できるようにしていきました。ちなみに、テンプレート化されたYAMLファイルは、記載された構成しか構築できません。そのため、新しい構成で構築したい場合はテンプレートから作成する必要があります。

このようにテンプレート化することでかなりミスを減らすことができますが、まだミスの混入の可能性があります。それは可変値の値を間違ってしまうということです。可変値のミスでありがちなのがARNのミスです。特に本番環境と開発環境のリソースを間違って、別のARNを書いてしまうようなケースです。ARNについては下記リンクを参照してください。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference-arns.html

誤って別のARNを指定してしまうと、大きな事故になります。そのため、私は可変値を全てデータベースに保存していました。データベースに保存された可変値とテンプレートを組み合わせてコードを自動生成すれば、ミスのないIaCを実現できます。ちなみに、データベースの内容を間違ったらミスが起きえるのでは?と思われるかもしれません。そこに関してはその通りなのですが、私の構築ポリシーとして、システムの構築要件をパラメータ化してデータベースに保存していました。要件のイメージとしては、EC2が何台、RDSはAurora PostgreSQLを使うというようなイメージです。これらの何台やサイズ、RDSの種類などを要件としてDBとして格納しておいて、それらを起点にコード生成して自動構築するイメージです。そういう要件の情報がセキュリティーホールに繋がることは少ないです。

二つのパターンを見比べてみる

特に後者の「ミスを無くしたいパターン」は、かなり構築負荷がかかっていることが想像できると思います。テンプレートの作成負荷もありますし、変数をセットしていくプログラムも必要になります。そういう意味では前者の「楽をしたいパターン」の何倍も労力がかかります。なので、重要なのは何を狙っているかです。楽に構築する世界観を追求するのか、セキュリティーを重視してミスをしないようにしたいのかで、できあがるIaCの環境は大きく異なります。

ちなみに、世の中のほとんどのIaC環境は「楽をしたいパターン」だと感じています。いろいろなセミナーのセッションを聞いていても、前者のパターンを事例としていることが多いです。ここからは私見になりますが、「ミスを無くしたいパターン」はかなり大規模の会社で、AWSアカウントが少なくとも数百あるような規模でなければコストがかかりすぎて実現できないと思います。そのため、狙いを決める上では自分たちの組織の規模や、会社の状況にも大きく左右されるので、そもそも自分たちが何を目指しているのかをよく考えてから実装と運用ルールを決めていくことをお勧めします。

Discussion