IT/AI救済センター

コラム / インフラ /

Terraform で始める Infrastructure as Code ─ OpenTofu との分岐・state の置き場所・drift との戦い方

📖 約8分 / 公開日: 2026/06/06

クラウドのリソースを管理コンソールでポチポチ作る運用は、3台目のサーバを立てたあたりで必ず破綻します。誰がいつ何を変えたのか追えなくなり、本番と検証環境の設定がいつの間にかずれ、退職者しか知らない手順が残る。Terraform を入れる動機は、流行りの技術だからではありません。この「誰も全体を把握していない」状態から抜け出すためです。

Infrastructure as Code、インフラの構成をコードとして書き、バージョン管理し、適用する考え方の代表格が Terraform です。AWS でも GCP でも Azure でも、Cloudflare や Datadog の設定まで、同じ書き方で宣言的に管理できます。「あるべき状態」をコードに書くと、現状との差分を Terraform が計算し、足りないものを作り、余ったものを消す。手順書を順番に実行するのではなく、到達したい状態を宣言する。この発想の転換が効きます。

## まず OpenTofu か Terraform かを決める

最初の分岐がここです。2023年8月、HashiCorp は Terraform のライセンスを従来の MPL から BSL(Business Source License)へ変更しました。競合する商用製品を作らない限り社内利用に実害はありませんが、この変更に反発して生まれたのが OpenTofu です。Linux Foundation 配下の完全な OSS フォークで、コマンドが tofu に変わるだけ、Terraform の構文である HCL はそのまま動きます。

中小企業の社内利用なら、正直どちらでも困りません。迷うなら OpenTofu を勧めます。ライセンスの不確実性を将来に持ち込まずに済み、機能差も実務上はほぼ感じません。以下のコマンドは terraform で書きますが、tofu に読み替えて構いません。

## state ファイルの置き場所だけは最初に正解を選ぶ

初心者が必ず踏む地雷が state(tfstate)です。Terraform は自分が何を作ったかを terraform.tfstate という JSON ファイルに記録します。これが現実とコードを突き合わせる台帳で、壊れたり消えたりすると Terraform は管理対象を見失います。

絶対にやってはいけないのが、この state を git にコミットすることです。state には DB のパスワードや生成された秘密鍵が平文で入ることがあり、リポジトリに上げた瞬間に漏洩します。複数人で同時に apply すれば、state そのものが壊れます。

正解はリモートバックエンドに置くこと。AWS なら S3 バケットに保存し、DynamoDB テーブルで排他ロックをかける構成が枯れています。これなら2人が同時に apply してもロックで弾かれ、state の破損を防げます。1人運用でも最初からこれにしてください。後から移行するより、リソースが空のうちに設定するほうが圧倒的に楽です。チームで本格的に回すなら、無料枠のある Terraform Cloud や Spacelift に state を預ける手もあります。

## plan を読む癖をつける

実務は terraform plan と terraform apply の往復です。plan は、適用したら何がどう変わるかを実行せずに見せてくれます。

apply の前に plan の出力を必ず読む。これだけは外さないでください。+ は作成、~ は変更、- は削除を意味します。この - を見落として本番の RDS が destroy 扱いになっていた、という事故は現実に起きています。名前やサブネットの変更が作り直しと判定されると、Terraform は既存リソースを消してから作り直そうとします。plan に "destroy and then create replacement" と出ていたら、一旦手を止める。それだけで多くの事故が防げます。

## 既存環境は import で取り込む

すでに手作業で作ったインフラがあるなら、ゼロから書き直す必要はありません。terraform import か、より新しい import ブロックで、既存リソースを state に取り込めます。

正直に言うと、import は地味につらい作業です。リソースごとに対応する HCL を自分で書き、属性を実物と一致させ、plan で差分ゼロになるまで詰める。100個のリソースがあれば、それなりの根気が要ります。Terraformer のような自動生成ツールもありますが、出力をそのまま使えることは稀で、結局は手直しが入ります。全部を一度に取り込もうとせず、変更頻度の高いものから IaC 化するのが現実的です。

## drift との戦いは終わらない

コードで管理し始めても、誰かが管理コンソールから手で設定を変えれば、コードと現実はずれます。これが drift(乖離)です。

drift を根本から防ぐには、本番への手作業を組織として禁じ、変更は必ず Terraform 経由にするしかありません。技術というより運用ルールの問題です。GitHub Actions や Atlantis を使い、プルリクエストに対して自動で plan を流し、レビューを通ったものだけ apply する仕組みを組むと、手作業の入る隙が減ります。tfsec や Checkov を CI に挟めば、公開しすぎた S3 バケットや穴だらけのセキュリティグループを apply 前に検出できます。

## 変数と秘密情報の扱い

環境ごとに違う値は variable と tfvars に逃がします。dev.tfvars、prod.tfvars と分け、apply 時に -var-file で切り替える。ここで気をつけたいのが、tfvars にもパスワードや API キーを書かないことです。state と同じ理屈で、平文の秘密情報がリポジトリに残ります。

DB パスワードのような秘密は、AWS なら SSM Parameter Store や Secrets Manager に置き、Terraform からは data ソースで参照する。値そのものはコードに現れず、参照だけがコードに残る形にします。それでも生成された値は state に書き込まれるため、state の保存先を S3 の暗号化バケットにし、アクセス権を絞る前提は崩せません。Terraform を入れれば秘密管理まで片付くわけではなく、秘密の置き場所は別途きちんと設計する。ここを混同すると、IaC 化したつもりで漏洩経路を増やすことになります。

## 小さく始める

Terraform を全インフラ一気に IaC 化する大プロジェクトと捉えると、まず頓挫します。

現実的な入り方は、新しく作る小さなリソース、たとえば検証用の VPC や S3 バケット1個から書き始めること。state のリモート化だけ最初にきちんとやれば、管理対象は少しずつ増やしていけます。module 化や workspace による環境分離は、コードが育ってから考えれば間に合う。最初から DRY を意識して抽象化に凝ると、読めないコードができて誰も触れなくなる。Terraform に限った話ではありませんが、IaC では特に起きやすい失敗です。

動くものを小さく作り、plan を読み、state を守る。この3つを押さえれば、ポチポチ運用には戻れなくなります。

関連コラム

具体的な状況をご相談ください

記事の内容に該当しそうなら、まずは60分の無料相談でご相談を。

60分無料相談を予約
緊急 AI診断 60分予約