IaC
IaCとは
IaC(Infrastructure as Code)は、サーバー・ネットワーク・データベースといったインフラの構成をコードで記述し、実行することで環境を構築する手法です。Terraform、AWS CloudFormation、Pulumi などのツールが代表例です。
# Terraformの例:仮想マシンを1台起動する定義
resource "aws_instance" "web" {
ami = "ami-xxxxxxxx"
instance_type = "t3.micro"
}
初学者向けポイント
- 従来は管理画面をクリックして手作業でサーバーを構築していた(俗に「クリックオペ」)。IaCはこれをコード化し、誰が実行しても同じ結果になる再現性を得る
- コード化されているので [[Git]] で変更履歴を管理でき、レビューを経てから適用できる。「いつ・誰が・何を変えたか」がインフラにも適用される
- 宣言的に書くのが主流([[Kubernetes]] のマニフェストと同じ発想)。「サーバーを1台起動しろ」ではなく「サーバーが1台ある状態にしろ」と書く
手続き型と宣言型
| スタイル | 特徴 | 例 |
|---|---|---|
| 手続き型 | 実行する操作を順に書く | シェルスクリプトでの構築 |
| 宣言型 | あるべき状態を書き、手順はツールが決める | Terraform、Kubernetesマニフェスト |
状態ファイルとドリフト
宣言型のツールは、コードと実物を突き合わせるために前回適用した結果を記録したファイル(state)を持ちます。差分は、コードとクラウドを直接比べて出しているのではなく、この記録を経由して計算されます。ここが初学者の最初のつまずきどころで、落とし穴が2つあります。
- ドリフト — 障害対応などで管理画面から手作業で設定を変えると、コードと実物がずれます。次回の適用でツールはコードに書かれた状態へ戻そうとするため、手で入れた修正が黙って巻き戻ります。緊急で手を入れたら、必ず後からコードにも反映して取り込みます
- stateの共有と機密 — state を各自の PC に置くと、2人が同時に適用したときに記録が食い違います。チームではクラウドのストレージなど共有の置き場に、同時実行を防ぐロック付きで保管します。state には接続情報などの値がそのまま入ることがあるため、[[Git]] にコミットしてはいけません([[シークレット管理]])
メリットと注意点
- メリット: 環境の複製(開発・検証・本番)が容易になる、構成変更の影響をコードのdiffで事前確認できる
- 注意点: 実際にクラウド上のリソースを変更・削除するため、
terraform applyのようなコマンドの実行前には必ず差分(plan)を確認する。誤って本番のデータベースを削除する事故が典型的な失敗例
planで「作り直し」を見つける
差分の出力は「作る」「変える」「壊す」に分かれます。特に怖いのは、変えるつもりが作り直しになるケースです。リソースには後から変更できない属性があり、そこを書き換えると、ツールは削除してから新規作成する計画を立てます。
# plan の出力例(抜粋)
# aws_db_instance.main must be replaced
-/+ resource "aws_db_instance" "main" {
-/+ や must be replaced が出たリソースは、中のデータごと消えて作り直される可能性があります。仮想マシン1台なら許せても、データベースなら本番障害です。適用の前に「壊す・作り直すが何件あるか」だけは必ず目視する、という約束をチームで決めておくと事故が減ります。
環境を増やすときはコピーしない
開発・検証・本番を用意するとき、最初にやりがちなのがディレクトリごとコードを複製することです。短期的には動きますが、同じ修正を3回入れることになり、やがて「本番だけ設定が古い」状態が生まれます。再現性という IaC 本来の狙いが失われるわけです。
共通部分はモジュール(部品)として切り出し、環境ごとに違うのは変数だけ、という形にします。台数やマシンサイズは変数で渡し、コードそのものは1つに保ちます。「環境ごとに変わるのは設定であってコードではない」という原則は、アプリ側と同じです。
CI/CDとの組み合わせ
IaCのコードも [[CI/CD]] のパイプラインに乗せ、プルリクエストのマージをトリガーに自動でインフラへ反映する運用が一般的です。アプリのコードとインフラのコードを同じ流儀で管理できます。
ここから先の地図
IaC は単体で完結しません。「何を作るのか」「中身をどう設定するのか」「どう安全に適用するのか」の3方向へ広がります。関心のある方向から進んでください。
作る対象を知る — コードで書く相手はクラウドのリソースです。[[クラウドコンピューティング]] でサービスモデルとリージョンの考え方を押さえ、[[AWS]] で EC2・S3・RDS といった実際のサービス名と対応づけると、Terraform のコードが「何を書いているか」として読めるようになります。アドレス空間や公開範囲を決めるネットワーク部分は [[VPCとクラウドネットワーク]] が担当範囲です。
中身を設定する — Terraform が担うのは箱を用意するところまでで、起動したサーバーの中に何を入れるかは [[Ansibleと構成管理]] の領域です。競合ではなく分担関係で、併用されます。一方、[[Docker]] でアプリを実行環境ごとイメージに固めてしまえば、サーバーの中身を後から設定する作業自体が減ります。多数のコンテナを宣言的に運用する [[Kubernetes]] のマニフェストも、発想としては IaC の延長線上にあります。
安全に適用する — コードは [[Git]] で履歴とレビューを残し、[[CI/CD]] のパイプラインから適用します。テンプレートに秘密の値を書かないための実務は [[シークレット管理]] に、適用に使う権限をどこまで絞るかの考え方は [[最小権限の原則]] にまとまっています。
なぜやるのかを知る — インフラをコード化する動機そのものは [[DevOps]] の文脈にあります。手作業を減らし、小さな変更を頻繁に安全に出す、という目的の一部が IaC です。
関連技術とのつながり
- [[クラウドコンピューティング]] — IaCが構築・管理する対象そのもの
- [[CI/CD]] — インフラ変更の適用もパイプラインに乗せて自動化する
- [[Docker]] / [[Kubernetes]] — コンテナ実行基盤の構築・設定もIaCの対象範囲
- [[Ansibleと構成管理]] — 用意したサーバーの中身を設定する側の代表ツール
- [[DevOps]] — IaCを実践として位置づける上位の考え方
Q: IaC で管理しているリソースを、管理画面から手作業で変更するとどうなる?
- [x] コードと実物がずれ、次回の適用で手作業の変更が巻き戻ることがある
- [ ] ツールが手作業の変更を自動でコードへ書き戻してくれる
- [ ] 以降そのリソースはIaCの管理対象から自動的に外れる
解説: この「ずれ」がドリフトです。緊急対応で手を入れたら、後からコードにも反映して取り込む必要があります。
Q: plan の出力に `must be replaced` と表示されたリソースについて、正しいのはどれ?
- [ ] 設定が変わるだけでデータはそのまま残る
- [x] 削除して作り直されるため、中のデータが失われる可能性がある
- [ ] 適用が必ずエラーで中断されるので安全
解説: 後から変更できない属性を書き換えると作り直しになります。データベースなら本番障害になり得るため、適用前に必ず目視します。
Q: 開発・検証・本番の3環境をIaCで用意するとき、推奨される作り方はどれ?
- [ ] 環境ごとにディレクトリを丸ごと複製し、それぞれ個別に修正する
- [x] 共通部分をモジュールとして切り出し、環境ごとの違いは変数で渡す
- [ ] 本番だけコードで管理し、開発と検証は手作業で構築する
解説: 複製すると同じ修正を何度も入れることになり、環境間の設定がずれていきます。コードは1つに保ち、変わるのは変数だけにします。