terraform init は、作業ディレクトリの初期化・backend(状態の保存先)・provider(クラウド SDK 相当)・モジュールの取得・依存ロックの作成を一括で行うコマンドです。
Associate 試験では、backend の再設定や state 移行時のフラグ、provider バージョン制約とロックファイルの扱いが頻出です。実務でも安全な初期化と再初期化の設計が欠かせません。
terraform init は main.tf などの設定を読み、必要な provider とモジュールを解決・取得し、backend を初期化します。初期化結果は .terraform ディレクトリと .terraform.lock.hcl(依存ロック)に反映されます。
実行フェーズは大きく「provider 解決」「module 取得」「backend 初期化」「ロックファイルの生成/更新」に分かれます。アップグレード時は -upgrade、backend を作り直すときは -reconfigure、state を移すときは -migrate-state を使います。
| 処理フェーズ | 生成/変更されるもの | 主な関連フラグ | 注意点 |
|---|---|---|---|
| Provider 解決 | .terraform/providers, .terraform.lock.hcl | -upgrade, -plugin-dir, -lockfile=readonly | ネットワーク制限下は TF_PLUGIN_CACHE_DIR を活用 |
| Module 取得 | .terraform/modules | -upgrade | モジュールのバージョンは source の ref などでも固定可能 |
| Backend 初期化 | リモート接続/ロック確認 | -backend-config, -reconfigure, -migrate-state | 資格情報はコードに直書きしない |
| 依存ロック更新 | .terraform.lock.hcl | -lockfile=readonly(更新抑止) | CI で勝手に書き換えない設計 |
init の俯瞰フロー
[main.tf] --parse--> (terraform init)
|---> [.terraform/providers]
|---> [.terraform/modules]
|---> [.terraform.lock.hcl]
\---> [Backend handshake + lock]最小構成の初期化例(ローカル backend)
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "local" {}
}
provider "aws" {
region = var.region
}
variable "region" {
type = string
default = "ap-northeast-1"
}
# 実行
# terraform initbackend は Terraform の状態ファイル(tfstate)の保存先を定義します。チーム運用ではローカルではなくリモート backend(例: S3、AzureRM、GCS)が基本です。S3 は DynamoDB を用いたロックが一般的、AzureRM は Blob のリース、GCS は世代管理を使った競合防止を行います(実装は各 backend 固有)。
既存環境で backend を切り替える場合、-reconfigure で再初期化、既存 state を安全に移すには -migrate-state を併用します。資格情報や機密は backend ブロックに直書きせず、-backend-config か環境変数で与えます。
| Backend 種別 | 保存先 | ロック戦略 | 実務メモ |
|---|---|---|---|
| local | ローカルファイル | なし | 個人検証用。チーム運用は非推奨 |
| s3 | S3 バケット + プレフィックス | DynamoDB テーブル | バケット/テーブルの権限と暗号化を必ず設計 |
| azurerm | Blob Storage コンテナ | Blob リース | storage_account_name などを backend-config で注入 |
| gcs | GCS バケット | オブジェクト世代管理に基づく | サービスアカウントの権限とバケットのロケーション統一 |
S3 backend とロックの関係
[Terraform CLI] --read/write--> [S3: tfstate]
| \
|---lock/unlock-----------> [DynamoDB: lock item]
|
\---credentials-----------> [IAM/環境変数/プロファイル]S3 backend 構成と安全な再初期化
# main.tf(資格情報は直書きしない)
terraform {
backend "s3" {}
}
# backend.hcl(例)
bucket = "my-tf-state"
key = "app/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "tf-lock"
encrypt = true
# 既存 local から S3 へ安全に移行(非対話)
terraform init \
-reconfigure \
-migrate-state \
-input=false \
-backend-config=backend.hclprovider は各プラットフォームの API クライアントです。terraform init は required_providers に基づき、Terraform Registry 等から適切なバイナリを取得し .terraform/providers に配置、ハッシュを .terraform.lock.hcl に記録します。
バージョン制約は実務・試験ともに重要です。~> 演算子で互換の範囲を指定、メジャー更新を避けつつマイナー/パッチを追従します。CI では TF_PLUGIN_CACHE_DIR を使いダウンロードを削減します。
| 演算子 | 例 | 解釈される範囲 | 用途/注意 |
|---|---|---|---|
| = | = 5.6.0 | 5.6.0 のみ | 完全固定。緊急時のピン留め |
| ~> | ~> 5.6.0 | >=5.6.0, <5.7.0 | パッチのみ自動追従 |
| ~> | ~> 5.0 | >=5.0.0, <6.0.0 | メジャー固定でマイナー/パッチ追従 |
| >= | >= 5.5.0 | 5.5.0 以上 | 上限なく危険。試験では推奨されない |
Provider 取得とキャッシュ
[Terraform CLI] --resolve--> [Terraform Registry]
| |
|--download--> [$HOME/.terraform.d/plugin-cache] (任意)
| |
\------deploy-------------> [.terraform/providers]
\-> [.terraform.lock.hcl]Provider 固定とキャッシュの設定例
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
}
}
provider "aws" {
region = var.region
}
# ダウンロードキャッシュ(シェル環境)
export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"
mkdir -p "$TF_PLUGIN_CACHE_DIR"
# 初期化(制約内で最新版へ)
terraform init -upgrade同一コードを dev/stg/prod で使い回す場合、backend 設定と資格情報を環境別ファイルに分離し、-backend-config で注入します。再初期化が必要な変更では -reconfigure、state 保存先を変えるときは -migrate-state を必ず併用します。
CI 実行では -input=false で非対話化し、-lockfile=readonly でロックファイルの予期せぬ更新を防ぎます。
| フラグ | 主用途 | 試験での要点 | 実務メモ |
|---|---|---|---|
| -reconfigure | backend を再初期化 | 既存設定を無視して再交渉 | プロンプト回避は -input=false 併用 |
| -migrate-state | state を新 backend に移行 | 安全な移行に必須 | dry-run はない。事前バックアップ推奨 |
| -backend-config | 機密/環境差の注入 | コード直書きしない | file と key=value の併用可 |
| -upgrade | provider/module の更新 | 制約内で最新選定 | PR で差分レビュー |
| -lockfile=readonly | ロック更新を禁止 | 再現性維持 | CI の既定にすると事故が減る |
1 つのコードを複数環境で初期化
[repo]
|-- main.tf
|-- backend-dev.hcl
|-- backend-stg.hcl
|-- backend-prd.hcl
[CLI] --dev--> terraform init -backend-config=backend-dev.hcl
[CLI] --stg--> terraform init -backend-config=backend-stg.hcl
[CLI] --prd--> terraform init -backend-config=backend-prd.hcl環境別 backend と CI 向け init コマンド
# backend-stg.hcl
bucket = "my-tf-state-stg"
key = "app/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "tf-lock-stg"
# backend-prd.hcl
bucket = "my-tf-state-prd"
key = "app/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "tf-lock-prd"
# ステージングを初期化(ロックファイルは読み取り専用)
terraform init \
-backend-config=backend-stg.hcl \
-input=false \
-lockfile=readonly
# 本番へ backend 切替と state 移行(CI)
terraform init \
-reconfigure \
-migrate-state \
-backend-config=backend-prd.hcl \
-input=false \
-lockfile=readonlybackend 再設定時の -migrate-state 抜け、provider バージョン不一致、ネットワーク制限下のダウンロード失敗は定番です。メッセージを鵜呑みにせず、.terraform ディレクトリ、.terraform.lock.hcl、backend 設定の三点を確認します。
Associate では、どのフラグを使えば安全に初期化/再初期化できるか、ロックファイルの扱い、資格情報の安全な注入方法が問われやすいです。
| 症状 | メッセージ抜粋 | 主原因 | 代表的な対処 |
|---|---|---|---|
| backend 切替後に plan で別 state 参照 | Backend configuration changed | -migrate-state を未実施 | terraform init -reconfigure -migrate-state |
| provider 解決失敗 | Failed to query available provider packages | バージョン制約/ネットワーク | 制約見直し、-upgrade、キャッシュ設定 |
| ロック競合 | Error acquiring the state lock | 別実行がロック保持 | 待機、DynamoDB ロック解放を確認(強制解放は最終手段) |
| ロックファイル更新を拒否したい | attempting to write lock file | CI で予期せぬ更新 | -lockfile=readonly で防止 |
よくある失敗パターン(backend 移行忘れ)
[local backend] --(state 残存)--> [開発者PC]
\
X terraform init(-migrate-state なし)
\
--> [S3 backend] --結果: state が分断/競合復旧・検証によく使うコマンド
# backend 再交渉 + state 安全移行
terraform init -reconfigure -migrate-state -backend-config=backend.hcl -input=false
# provider を制約内で再選定
terraform init -upgrade
# 異種プラットフォーム向けにロック事前生成(複数 OS/CPU)
terraform providers lock -platform=linux_amd64 -platform=darwin_amd64
# どうしても壊れたときの最終手段(要注意)
# rm -rf .terraform && terraform initAssociate
問題 1
ローカル backend で運用していた既存プロジェクトを、S3 backend(DynamoDB ロック付き)へ移行します。既存 state を安全に移し、CI で非対話的に実行したい。最も適切なコマンドはどれですか?
正解: A
backend の再初期化には -reconfigure、既存 state を新 backend に安全移行するには -migrate-state が必要。CI 非対話は -input=false、機密は -backend-config で注入する。-upgrade は provider/module 更新であり、backend 移行の要件を満たさない。terraform state push は通常の移行手順として推奨されない。
terraform init はいつ実行すべきですか?
リポジトリを初回 clone したとき、provider・module・backend の設定やバージョン制約を変更したとき、.terraform ディレクトリを削除したときに実行します。plan/apply の前提です。
.terraform.lock.hcl は VCS に含めるべきですか?
はい(ルートモジュールでは推奨)。これにより provider バイナリのハッシュが固定され、再現性が担保されます。再利用モジュールの公開リポジトリでは方針により除外する場合もありますが、チームのルートコードではコミットするのが一般的です。
backend ブロックにアクセスキー等を書いてもよいですか?
推奨しません。資格情報や機密は -backend-config、環境変数、プロファイル、OIDC/Federation 等で注入します。試験でも「コードに機密を直書きしない」設計が正解です。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...