Immutable InfrastructureとIaCの基礎

# はじめに  
本文書は、初めてコンテナ技術を学ぶ方向けに、この技術の意義や位置づけを概説するものです。  
理解しやすさを優先し、一部の概念を単純化して説明していますが、大枠の理解を深めることを目的としています。

## 従来のインフラ構築作業における課題  
![HandFlow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/adb2adcb-916c-41cb-b6ae-4cf07e68f1ec.png)

従来のインフラ構築は設計、構築、テストをすべて手作業で行うことが一般的でした。サーバの台数が増えるほど、構築期間が長くなり、作業量も増加するという課題がありました。さらに、以下のような問題も生じていました。

### 状態を管理できない  
手作業によるインフラ構築では、環境の状態を厳密に定義することが困難です。  
構築後の環境は、障害対応や一時的な変更、人的ミスなどによって意図せず変化します。その結果、同じ状態を再現することが難しくなり、作業のやり直しやトラブル対応が困難になります。

![Container-手作業の戻し.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/e48b69c3-e893-4506-8987-06e7286d41e3.png)

例えば、作業を一世代前の状態に戻すことは可能かもしれません。しかし、その間に別の変更が加えられていれば、元の状態とは言えなくなります。二世代以上前に戻すことは、さらに困難になります。

### 同じミスを繰り返す  
手作業では、ヒューマンエラーを完全に防ぐことはできません。同じ環境を数十台構築する際、たった一つのミスを見つけるのは非常に困難です。  
その結果、作業の品質は向上しにくく、担当者のスキルに強く依存してしまいます。

## Immutableなインフラストラクチャとは  
この「環境の状態を管理できない」問題を解決する方法の一つが、**Immutable Infrastructure（変更不可なインフラストラクチャ）**です。

このアプローチでは、既存の環境を直接変更するのではなく、新しい環境をゼロから構築し、古い環境を廃棄することで運用します。これにより、環境を作り直す手順が明確になり、意図しない変更を排除できます。
![Container-Immutable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/ba14d88f-5b8d-4764-b813-430a9f3011bd.png)
Immutable Infrastructureでは、環境は使い捨てとされ、変更が必要な場合は新しい環境を構築して置き換えます。この考え方から、「Immutable（変更できない）」という名称が付けられています。

## Immutableなインフラストラクチャの課題  
このアプローチには多くの利点がありますが、一つの大きな課題があります。**作業量が膨大になる**ことです。

新しい環境を毎回ゼロから構築するため、手作業で行うと時間と労力がかかりすぎてしまいます。この問題を解決する手段として**Infrastructure as Code（IaC）**が登場しました。

### IaCの導入  
作業量の問題は、自動化することで解決できます。同じ作業を繰り返すのはコンピュータの得意分野です。  
AnsibleなどのIaCツールを導入することで、環境構築の自動化が可能になります。

![IaCflow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/ffb38eae-f418-4c4b-ba42-bb51e4b8831c.png)

IaCツールの多くは「冪等性」を重視しています。従来のシェルスクリプトのように逐次的な手順を実行するのではなく、**「あるべき状態」を定義し、その状態を実現する**という考え方に基づいています。

IaCを導入することで、
- 環境の構築を自動化し、作業ミスを防ぐ
- 何度実行しても同じ結果を保証する
- コードとして環境の定義を管理し、再現性を確保する

といったメリットを得ることができます。

#### IaCツールの例 Ansible

Ansibleは、エージェントレスな構成管理ツールとして広く利用されています。  
Pythonで書かれたシンプルな設計で、SSHを利用してリモートホストを管理できるため、追加のソフトウェアをインストールする必要がなく、導入の手間が少ないのが特徴です。

##### Ansibleの特徴
1. **エージェントレス**  
   - 他の構成管理ツール（PuppetやChef）とは異なり、リモートノードにエージェントをインストールする必要がありません。
   - SSH経由でコマンドを実行するため、シンプルな構成で運用が可能です。

2. **宣言的な構成管理**  
   - Ansibleでは、「あるべき状態（desired state）」をYAML形式のPlaybookとして記述します。
   - 例えば、「nginxがインストールされている」「特定の設定ファイルが配置されている」といった状態を記述し、Ansibleがその状態を実現します。

3. **冪等性（Idempotency）**  
   - Ansibleは、何度実行しても同じ結果を保証するように設計されています。
   - 例えば、「nginxをインストールする」タスクがすでに適用済みの場合、再実行しても何も変更されません。

4. **簡潔で分かりやすい記述**  
   - Playbook（設定ファイル）はYAMLで記述されるため、可読性が高く、学習コストが低いです。
   - 例：
     ```yaml
     - name: Install and start nginx
       hosts: webservers
       become: true
       tasks:
         - name: Install nginx
           apt:
             name: nginx
             state: present

         - name: Start nginx
           service:
             name: nginx
             state: started
     ```

5. **柔軟な適用範囲**  
   - 小規模なサーバ管理から大規模なクラウド環境のオーケストレーションまで幅広く対応。
   - AWS、Azure、GCPなどのクラウドプロバイダと統合可能。

##### Ansibleの導入メリット
- 手作業のインフラ構築を自動化し、**再現性のある環境**を実現。
- 複数台のサーバに対して、同じ設定を一括適用できる。
- 冪等性により、安全な構成管理が可能。

Ansibleは、シンプルな構成管理とオーケストレーションを実現するIaCツールとして、DevOps環境で広く活用されています。

### IaCの課題  
IaCツールは便利ですが、単体ではいくつかの課題があります。  
例えば、プロビジョニング対象のサーバがIaCツールを実行できる状態になるまでには、「OSのインストール」や「通信受け入れの設定」、ツールによっては「プロビジョニングエージェント」の導入が必要になります。

この問題は、事前に必要なソフトウェアを導入したVirtual Machineを用意することで、ある程度は対処可能ですが、「ネットワークアドレス」などインスタンスごとに設定が必要な場合もあり、完全な自動化には至りません。

この問題に対するアプローチとして、
- 仮想化環境のヘッドレスエージェントを宣言的に利用する
- 仮想化レイヤを従来の物理マシンからOSレベルに引き上げる

という方法が挙げられます。前者のアプローチを採用したのがHashiCorpのVagrant、後者のアプローチを採用したのがDockerコンテナです。

詳細なコンテナ仮想化については、次回に解説します。

## まとめ  
従来の手作業によるインフラ構築には、
- 状態を管理できない
- 作業ミスを防げない
- スキルに依存する

といった課題がありました。Immutable Infrastructureを採用することで、環境の管理をシンプルにし、意図しない変更を排除できます。ただし、作業量の増大という課題があり、これを解決する手段としてIaCが有効です。

Immutable InfrastructureやIaCは、クラウド環境においても重要な技術であり、今後さらに普及することが予想されます。これらを理解し、活用することで、より柔軟でスケーラブルなシステム運用が可能となるでしょう。