インフラストラクチャはどこから来るのか
チームがアプリケーションの開発を始めるとき、最初に上がる質問はほぼ常にコードに関するものです。どの言語を使うか、ディレクトリ構成はどうするか、ローカルマシンでどう動かすか。インフラに関する質問はたいてい後回しにされ、アプリを他の人がアクセスできる場所で動かす必要が出てきて初めて話題になります。
ここからが面白いところです。インフラは自動で出現しません。サーバー、データベース、ネットワーク、ロードバランサー——これらはすべて作成、設定、接続される必要があります。最もシンプルな方法は手動で行うことです。クラウドのダッシュボードにログインし、ボタンをクリックしてサーバーを作成し、スペックを選び、準備ができるのを待つ。これでサーバー1台なら問題ありません。しかし、複数のサーバーを管理する場合、ステージング環境と本番環境が必要な場合、あるいは何かが壊れてすべてをゼロから再構築しなければならない場合、この方法は破綻し始めます。
問題は時間だけではありません。インフラを手動で作成すると、実際に何が構築されたかの信頼できる記録が残りません。開発者Aは特定のスペックでサーバーを作成する一方、開発者Bは少し異なる設定で別のサーバーを作成するかもしれません。理由は単純に忘れたか、クラウドダッシュボードのインターフェースが変わったからかもしれません。こうした小さな差異は、追跡が困難なバグを引き起こします。コードが同一でも、アプリケーションはステージングでは正常に動作するのに本番では失敗する、といった具合です。
手動のインフラは再現も困難です。チームが新しい環境——例えばQAテスト用やクライアントデモ用——を必要とする場合、プロセス全体をゼロから繰り返さなければなりません。そのたびに、ステップを飛ばしたりパラメータを誤設定したりするリスクがあります。インフラが大きくなればなるほど、意図した状態と実際に作成される状態の乖離は広がります。
インフラをコードとして扱う
より良いアプローチは、インフラをアプリケーションコードと同じように扱うことです。人間が読めるテキストファイルに記述し、それらのファイルをリポジトリに保存し、通常のコードと同じプロセスで管理します。これらのファイルは、いわゆる*ディザイアードステート(望ましい状態)*を定義します。サーバーのスペック、ディスクサイズ、ファイアウォールルール、データベース接続などを含む、インフラの理想的な状態です。
このアプローチでは、誰も手動の手順を覚えておく必要も、誰かの記憶に頼る必要もありません。すべてのインフラ定義は、チームの誰もが閲覧、レビュー、変更できるファイルに格納されます。インフラへの変更は、コード変更と同じパイプラインを通過します。すなわち、記述、チームメイトによるレビュー、承認後の適用です。
Terraformでのシンプルなインフラ定義の例を以下に示します。
resource "aws_instance" "app_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServer"
}
}
この概念は*Infrastructure as Code(IaC)*と呼ばれます。考え方は単純です。インフラは一度設定して忘れるものではありません。アプリケーションのライフサイクルを通じて定義、バージョン管理、管理するものです。これにより、ステージング環境と本番環境が同一であること、すべての変更が追跡可能であること、そして手順の抜け漏れを心配せずにいつでも新しい環境を立ち上げられることを確信できます。
手動インフラがスケールしない理由
具体的に考えてみましょう。チームが10台のサーバーを手動で管理しているとします。ある日、1台のサーバーがクラッシュしました。交換する必要があります。ダッシュボードにログインし、新しいサーバーを作成し、古いサーバーの設定を思い出そうとします。インスタンスタイプは同じだったか?セキュリティグループのルールは同じか?ディスクサイズは?正しく設定できるかもしれませんが、できないかもしれません。そして、たとえ正しく設定できたとしても、それを証明する方法はありません。
では、まったく新しい環境——例えばパフォーマンステストチーム用——を作成する必要がある場合を想像してください。すべての手動ステップをゼロから繰り返さなければなりません。インフラがデータベース、ロードバランサー、キャッシュ層、メッセージキューを含むように成長している場合、手動プロセスは何時間もかかるチェックリストとなり、あらゆるステップで人為的ミスが発生する可能性があります。
本当のコストはボタンをクリックする時間ではありません。不確実性です。本番で問題が発生したとき、「インフラで何が変わったのか?」「この環境はステージングとまったく同じ設定か?」といった質問にすぐに答えられません。Infrastructure as Codeがなければ、これらの質問に自信を持って答えることは困難です。
Terraformワークフローはここから始まる
ここからTerraformワークフローが始まります。コマンドを実行する前に、チームは設定ファイルにインフラ定義を記述します。これらのファイルが信頼できる唯一の情報源(シングルソースオブトゥルース)となります。クラウドダッシュボードでも、個人のメモでも、誰かの記憶でもありません。
ワークフローはシンプルなサイクルに従います。
Write(記述) -- 設定ファイルにインフラを定義します。必要なサーバー、ネットワーク、データベース、その他のリソースを記述します。
Plan(計画) -- Terraformに、適用前に何が変更されるかを表示させます。これにより、レビューしてミスを発見する機会が得られます。
Apply(適用) -- 変更を実行します。Terraformは設定を現在のインフラ状態と比較し、望ましい状態に到達するために必要な変更のみを行います。
このサイクルは、アプリケーションコードの作業方法を反映しています。コードを書き、レビューし、デプロイします。違いは、アプリケーションロジックをデプロイする代わりに、インフラ定義をデプロイする点です。そして、アプリケーションコードと同様に、これらの定義はバージョン管理下に置かれ、コードレビューを経て、本番環境に到達する前にテストされます。
Infrastructure as Codeがもたらす変化
Infrastructure as Codeを採用すると、チームの運用方法にいくつかの変化が生じます。
監査可能性が自動化されます。 インフラへのすべての変更はバージョン管理履歴に記録されます。誰が、いつ、なぜ変更したかを確認できます。本番で問題が発生した場合、インフラの変更が問題と同時期に発生したかを確認できます。
一貫性が実現可能になります。 同じ設定ファイルを使用して、開発、ステージング、本番で同一の環境を作成できます。環境間の差異は、偶発的なものではなく、意図的かつ文書化されたものになります。
復旧が再現可能になります。 環境が破損したり、再構築が必要になったりしても、手動の手順を覚えておく必要はありません。同じ設定ファイルを実行するだけで、定義されたとおりにインフラが再作成されます。
コラボレーションが可能になります。 インフラ定義はコードのようにレビューできます。ジュニアメンバーは既存の設定を読んで学習できます。シニアメンバーは本番環境に到達する前にミスを発見できます。
実践的なスタート地点
Infrastructure as Codeが初めての場合、以下のシンプルなチェックリストから始めてみてください。
- 現在手動で管理している小さなインフラ要素を1つ選びます。例えば、1台のサーバーやデータベースインスタンスなどです。
- Terraformまたは選択したIaCツールでその設定を記述します。
- プランを実行して、Terraformが何を変更するかを確認します。
- 設定を適用し、結果が期待通りであることを確認します。
- 設定ファイルをリポジトリにコミットします。
- 手動で作成したリソースを削除し、設定ファイルのみを使用して再作成します。
この演習により、自分自身とチームに対して、このアプローチが機能することを証明できます。一度成功すれば、同じ方法で管理すべき他のインフラ部分が見えてくるでしょう。
まとめ
インフラは魔法のように出現するものではなく、記憶によって管理されるべきものでもありません。Infrastructure as Codeとして記述することで、エラーが発生しやすい手動プロセスを、再現可能で、レビュー可能で、監査可能なワークフローに変えることができます。Terraformワークフロー(Write、Plan、Apply)は、このアイデアの実用的な実装にすぎません。コマンドを実行する前に、まず何を望むかを定義してください。その定義をバージョン管理に保存することで、インフラの唯一の信頼できる情報源となります。そこからすべてが始まります。