Terraformの-targetは特定のリソースやモジュールだけを計画・適用するためのオプションです。便利に見えますが、公式ドキュメントでも日常的利用は非推奨と明言されており、依存関係の取り扱いを誤ると状態の不整合を生む原因になります。
本記事では、-targetの挙動を依存グラフとStateの観点から解説し、現場でどうしても必要な場面に限定して安全側に使うための手順と、より推奨される代替手段をまとめます。Associate試験の出題傾向も踏まえて要点を押さえます。
-targetは、アドレス指定したオブジェクト(リソースやモジュール)に関わる部分だけを計画・適用の対象に絞り込みます。対象の依存元(必要な前提)は自動で含めますが、対象に依存する後続は含めません。
HashiCorpの公式ドキュメントでは、-targetは復旧や回避のための例外的な用途に限ることが推奨されています。日常運用で多用すると、依存関係外の更新が置き去りになり、次回フル適用時に意図しない差分が出るリスクがあります。
適用方法はplanにもapplyにも指定できますが、まずplanで差分を確認し、レビュー後に適用するのが安全です。保存した計画ファイルを使う場合、その計画は対象のみに限定された内容になります。
基本的な実行例
terraform plan -target=module.app -target=aws_instance.web[0]
terraform apply -target=module.app
# 計画を保存してから適用
terraform plan -target=aws_security_group.web -out=plan.tfplan
terraform apply plan.tfplanTerraformは依存グラフに基づいて実行順序を決めます。-targetを指定すると、指定オブジェクトとその依存元だけをグラフから抽出して処理します。依存先(ターゲットに依存する側)は除外されるため、連鎖的な更新は行われません。
そのため、ターゲットのアップデートが依存先の入力に影響する設計の場合、依存先は未更新のまま残ります。これが次回のフル適用で大きな差分や再作成(create-before-destroy等)を誘発する温床になります。
ターゲット指定時の依存グラフの切り出し
A (vpc)
\
B (subnet) --> D (instance)
/
C (sg)
-target=B の場合:
含まれる: B と Bが依存する A(必要なら)
含まれない: Bに依存する D、C(Bが参照しないなら)依存関係の例(HCL)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "app" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
}
resource "aws_instance" "web" {
subnet_id = aws_subnet.app.id
# ...
}
# -target=aws_subnet.app は VPC を含むが、aws_instance.web は処理されない部分適用を繰り返すと、Stateは最新でも、未対象のリソースがクラウド側と乖離している可能性が高まります。次のフルplanで大量の差分が出て、計画レビューが困難になるケースが典型です。
count/for_eachで配列やマップを扱う場合、一部だけ更新するとインデックスの再配置やKey追加が次回フル適用で予期せぬ置換を招くことがあります。ライフサイクルのcreate_before_destroyやignore_changesの設定との相互作用にも注意が必要です。
Outputsやモジュールの出力は、ターゲット外だと古い値のまま参照されることがあります。依存が間接的でも、フル適用で整合させる前提で運用してください。
差分の見え方の比較
# 部分適用
terraform plan -target=module.db
terraform apply -target=module.db
# 直後にフルplanで整合性確認
terraform plan # ここでappやnetworkに差分が出ないか確認
# count/for_eachの変更が絡むときは特に注意
# 例: for_eachの元データに要素追加後、部分適用で一部だけ作成 → フル適用時に再配置が発生することがある公式が想定するのは、トラブル切り分けや外部制約を回避するための一時的措置です。たとえば、特定のリソースでプロバイダのAPI制限に当たって全体が進まない場合、そのリソースを除外して他を先に進める、あるいは逆に必要最小限だけ先に作る、といった用途です。
安全に使うためには、対象の明確化、差分の十分なレビュー、適用後のフルplanチェック、短期間でのフル適用による整合性回復、のサイクルを徹底します。
複数ターゲットの指定と段階的適用
# 依存順にターゲットを刻む(例)
terraform plan -target=aws_vpc.main -target=aws_subnet.app
terraform apply -target=aws_vpc.main -target=aws_subnet.app
# 先行作成後にアプリ層
terraform plan -target=module.app
terraform apply -target=module.app
# 必ず最後にフルplan
terraform plan多くのケースで、-targetより安全な手段があります。特定オブジェクトの置換には -replace、状態のみ最新化したいなら -refresh-only、構成を分割してBlast Radiusを小さくするならスタック分割(ワークスペースやレポ分割)を検討します。
また、構成変更時はmovedブロックでリネームを明示し、ignore_changesで一時的なドリフトを許容するなど、計画を安定させる手当ても有効です。部分適用を使った後は、短期間で必ずフル適用して収束させる、という運用ルールを決めておくと事故が減ります。
| 手段 | 主目的 | 影響範囲と特性 | 主なリスク/注意点 |
|---|---|---|---|
| -target | 部分的な計画/適用 | 指定対象とその依存元に限定。依存先は除外 | 日常利用は非推奨。未更新部分が次回フル適用で大差分に |
| -replace=ADDR | 特定オブジェクトの再作成 | 対象のみを置換。依存関係は通常のグラフで評価 | ダウンタイムやIP変更などの影響に注意 |
| -refresh-only | 実インフラの状態をStateに反映 | 作成/変更/削除は行わない。読み取りのみ | ドリフトの可視化には有効だが差分解消は別途必要 |
代替手段の具体例
# 置換が目的なら -replace を優先
terraform plan -replace=aws_instance.web[0]
terraform apply -replace=aws_instance.web[0]
# 状態だけ最新化して影響を見たい場合
terraform plan -refresh-only
terraform apply -refresh-only
# リソース名の変更や移動は moved ブロックで明示
moved {
from = aws_security_group.old
to = aws_security_group.new
}出題では、-targetの性質(例外的な利用、依存元のみ含まれる、依存先は含まれない)とリスク認識が問われやすいです。日常的な運用として推奨されるかどうか、代替手段の選択も判断ポイントになります。
また、アドレス指定の粒度(リソース、モジュール、インスタンスインデックス)、計画ファイルに反映される範囲、適用後のフルplanの重要性など、現場での運用手順と結び付けて覚えておくと選択肢で迷いにくくなります。
試験で混同しやすいコマンド例の整理
# 部分適用(例外的)
terraform plan -target=module.app
terraform apply -target=module.app
# 置換(推奨される明示的な再作成)
terraform apply -replace=aws_db_instance.main
# 状態のみ反映
terraform plan -refresh-onlyAssociate
問題 1
チームは特定のサブネットとそれに依存するインスタンスだけを先に作成したいと考えています。Terraformの-targetを使う場合の挙動として最も正しいのはどれですか?
正解: A
-targetは指定オブジェクトとその依存元を含めますが、依存先は含みません。従って、サブネットをターゲットにすると、VPCなどの依存元は含まれますが、そのサブネットに依存するインスタンスは含まれません。
-targetをモジュールに指定すると、そのモジュール配下はすべて対象になりますか?
基本的にそのモジュール配下のリソースが対象になります。ただし、モジュール外の依存元があればそれも含まれます。一方で、そのモジュールに依存する別モジュール(依存先)は含まれません。
部分適用の後にterraform refreshは必要ですか?
現行のTerraformではrefresh専用コマンドではなく、-refresh-onlyを付けたplan/applyで状態の同期が行えます。部分適用後に差分確認のためterraform plan(フル)を実行し、必要に応じてterraform plan -refresh-onlyで状態だけを更新してから、最終的にフル適用で収束させるのが安全です。
depends_onで明示的に依存させている場合、-targetの挙動は変わりますか?
挙動は変わりません。-targetは指定対象とその依存元(明示/暗黙を問わず)を含めますが、依存先は含みません。depends_onは依存関係の定義に影響しますが、-targetの“依存先は含めない”という性質はそのままです。
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を用いた既存リソース参照の基本、選択基準、評価順序、...