Terraform's -target option lets you plan and apply just a specific resource or module. It looks convenient, but the official documentation explicitly discourages everyday use — mishandling the dependency relationships is a common source of state inconsistency.
This article walks through -target from the perspective of the dependency graph and state, lays out a safe procedure for the limited situations where you really need it, and summarizes the alternatives Terraform recommends instead. We also cover the points the Associate exam tends to ask about.
-target narrows the plan/apply scope to just the addressed object (a resource or a module) and its surroundings. Upstream prerequisites the target needs are pulled in automatically, but downstream dependents that rely on the target are not.
HashiCorp's documentation recommends -target only as an exceptional measure for recovery or workarounds. Leaning on it in day-to-day operations leaves updates outside the dependency chain stranded, and the next full apply tends to surface unexpected drift.
You can pass -target to both plan and apply, but the safe pattern is to plan first, review the diff, and then apply. If you save a plan file, that plan is itself scoped to the targeted objects only.
Basic command examples
terraform plan -target=module.app -target=aws_instance.web[0]
terraform apply -target=module.app
# Save the plan, then apply it
terraform plan -target=aws_security_group.web -out=plan.tfplan
terraform apply plan.tfplanTerraform decides execution order from the dependency graph. -target extracts just the targeted object and its upstream dependencies from that graph and processes them. Dependents (the side that depends on the target) are excluded, so downstream updates do not cascade.
As a result, if the target's update changes the inputs of a dependent, that dependent stays stale. This is exactly what drives large diffs or surprising replacements (create-before-destroy and friends) on the next full apply.
How the dependency graph is sliced when you target
A (vpc)
\
B (subnet) -> D (instance)
/
C (sg)
With -target=B:
Included: B and A (the upstream B depends on, if needed)
Excluded: D (depends on B), C (unless B references it)Example of these dependencies in 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 includes the VPC, but aws_instance.web is not processedRepeated partial applies tend to leave non-targeted resources drifting from what's actually in the cloud, even when state itself is up to date. The classic symptom is that the next full plan emits a huge diff and becomes hard to review.
With count/for_each over lists or maps, updating only part of the set can cause index reshuffling or new-key insertions to trigger unexpected replacements on the next full apply. Watch out for interactions with lifecycle settings like create_before_destroy and ignore_changes as well.
Outputs and module outputs can keep returning stale values when they sit outside the target scope. Even when the dependency is indirect, operate on the assumption that you will reconcile everything with a full apply afterwards.
What the diffs look like in each case
# Partial apply
terraform plan -target=module.db
terraform apply -target=module.db
# Immediately verify consistency with a full plan
terraform plan # Check whether the app or network layer surfaces unexpected diffs
# Be especially careful when count/for_each changes are involved
# Example: after adding an element to the for_each source, a partial apply that creates only some entries can trigger reshuffling on the next full applyThe official intent is a temporary measure for triage or for working around external constraints. For instance: a specific resource is hitting a provider API limit and blocking everything else, so you either skip it and move the rest forward, or do the inverse and create just the minimum prerequisite up front.
To use it safely, stick to the cycle: clearly identify the target, review the diff thoroughly, run a full plan check after the apply, and close the loop by converging with a full apply within a short window.
Specifying multiple targets and staged application
# Slice targets in dependency order (example)
terraform plan -target=aws_vpc.main -target=aws_subnet.app
terraform apply -target=aws_vpc.main -target=aws_subnet.app
# Application layer after the prerequisites are created
terraform plan -target=module.app
terraform apply -target=module.app
# Always finish with a full plan
terraform planIn most cases there's a safer option than -target. For replacing a specific object, use -replace; for refreshing state without changes, use -refresh-only; to shrink blast radius structurally, split the configuration into separate stacks (workspaces or repos).
When restructuring, declare renames explicitly with moved blocks and allow temporary drift with ignore_changes — small touches that stabilize the plan. Establishing a rule that every partial apply must converge with a full apply within a short window also cuts down on incidents.
| Mechanism | Primary purpose | Scope and characteristics | Main risks and caveats |
|---|---|---|---|
| -target | Partial plan/apply | Limited to the target and its upstream dependencies. Dependents are excluded | Not recommended for everyday use. Unmodified parts surface as a large diff on the next full apply |
| -replace=ADDR | Re-create a specific object | Replaces only the target. Dependencies are evaluated via the normal graph | Watch for side effects like downtime or IP address changes |
| -refresh-only | Reflect real infrastructure state into Terraform state | No create/update/delete — read-only | Useful for surfacing drift, but you still need a separate apply to reconcile diffs |
Concrete examples of the alternatives
# Prefer -replace when the goal is replacement
terraform plan -replace=aws_instance.web[0]
terraform apply -replace=aws_instance.web[0]
# When you just want to refresh state and see the impact
terraform plan -refresh-only
terraform apply -refresh-only
# Declare renames and moves explicitly via moved blocks
moved {
from = aws_security_group.old
to = aws_security_group.new
}Exam questions tend to probe the nature of -target (exceptional use only, upstream included, downstream excluded) and your awareness of its risks. Whether it is recommended for everyday operations and which alternative you would pick are common decision points.
Connecting the topic to operational practice — address granularity (resource, module, instance index), what ends up in the plan file, the importance of a full plan after the apply — makes the answer choices easier to navigate.
Sorting out the commands that are easy to mix up on the exam
# Partial apply (exceptional)
terraform plan -target=module.app
terraform apply -target=module.app
# Replacement (the recommended way to explicitly re-create)
terraform apply -replace=aws_db_instance.main
# State sync only
terraform plan -refresh-onlyAssociate
問題 1
A team wants to create just a particular subnet and the instances that depend on it first. When using Terraform's -target option, which of the following best describes the behavior?
正解: A
-target includes the targeted object and its upstream dependencies, but never its downstream dependents. Targeting the subnet therefore pulls in upstream resources like the VPC, while the instances that depend on the subnet are left out.
If I point -target at a module, does it include everything under that module?
Yes — the resources under that module are included by default. Any dependencies outside the module that the target needs are also pulled in. However, other modules that depend on the target module (downstream dependents) are not included.
Do I need to run terraform refresh after a partial apply?
Modern Terraform no longer has a dedicated refresh command — you sync state via plan/apply with the -refresh-only flag. The safe pattern after a partial apply is: run a full terraform plan to inspect drift, use terraform plan -refresh-only to update state only if needed, and finally run a full apply to converge.
Does depends_on change how -target behaves?
No, it does not. -target includes the target object and its upstream dependencies (whether implicit or explicit via depends_on), but never its downstream dependents. depends_on shapes the dependency graph itself, but the rule that -target excludes dependents still holds.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
HCL Syntax: Terraform's Configuration Language (2026)
HCL2 fundamentals for Terraform — blocks, attributes, expres...
Terraform Authoring & Operations Pro: Complete Guide (2026)
Tactics for the Terraform Pro exam — module authoring, works...
Terraform Providers: Plugin Management Fundamentals (2026)
Provider mechanics — required_providers, versions, mirrors, ...
Terraform Resource Blocks: Declarative Infra Units (2026)
Resource block fundamentals — addresses, references, common ...
Terraform Data Sources: Read-Only External Data (2026)
Data source basics — declaration, refresh behavior, dependen...