Terraform Target Flag for Selective Plan Apply Destroy

Terraform target is the operational mechanism that lets operators narrow plan, apply, or destroy execution to a specific resource, module, or collection of resources instead of the entire configuration. The -target flag tells Terraform to focus on a chosen part of the dependency graph. It is presented in the reference materials as a troubleshooting tool for one-off fixes, for accelerating changes in large deployments, and for recovering from state drift caused by network failures, upstream cloud platform problems, or bugs in Terraform or its providers. HashiCorp explicitly recommends using resource targeting only for exceptional situations, not as a default deployment strategy. Routine use creates partial updates, skipped changes, and long-term drift.

The flag works identically across terraform plan, terraform apply, and terraform destroy. Without -target, those commands take the entire configuration into account. With -target, Terraform selects a directly targeted instance and then extends the selection to include all other objects that those selections depend on either directly or indirectly. Upstream prerequisites get planned and applied alongside the target. Downstream resources that depend on the target are not automatically included, which is why partial applies often cause drift.

Targeting individual resources can be useful for troubleshooting errors, but should not be part of your normal workflow. The reference materials repeat this warning across multiple sources. The typical Terraform workflow applies the entire plan at once. Occasionally you may want to apply only part of a plan when Terraform's state has become out of sync with your resources.

What Terraform Target Is

In Terraform, -target is a command-line option that lets you plan or apply changes to specific resources or modules only, instead of your entire configuration. It is handy for troubleshooting, one-off fixes, or accelerating changes in large deployments.

However, -target tells Terraform to focus on just part of the dependency graph. This can lead to partial updates, skipped changes, and long-term drift if you rely on it in routine workflows. HashiCorp explicitly recommends using resource targeting only for exceptional situations, not as your default deployment strategy.

The option accepts a resource address. The format is <module_path>.<resource_identifier>.

Terraform will also apply changes to all resources that depend on that module, so be sure to understand the dependencies in your Terraform configuration before targeting a module.

When you apply changes to your Terraform projects, Terraform generates a plan that includes all of the differences between your configuration and the resources currently managed by your project, if any. When you apply the plan, Terraform will add, remove, and modify resources as proposed by the plan.

You can use Terraform's -target option to target specific resources, modules, or collections of resources. The tutorial referenced in the materials provisions an S3 bucket with some objects in it, then applies changes incrementally with -target.

You can complete this tutorial using the same workflow with either Terraform Community Edition or HCP Terraform. HCP Terraform is a platform that you can use to manage and execute your Terraform projects.

How Targeting Is Addressed

Terraform interprets the resource address as follows.

If the given address identifies one specific resource instance, Terraform will select that instance alone. For resources with either count or for_each set, a resource instance address must include the instance index part, like aws_instance.example[0].

If the given address identifies a resource as a whole, Terraform will select all of the instances of that resource. For resources with either count or for_each set, this means selecting all instance indexes currently associated with that resource. For single-instance resources (without either count or for_each), the resource address and the resource instance address are identical, so this possibility does not apply.

If the given address identifies an entire module instance, Terraform will select all instances of all resources that belong to that module instance and all of its child module instances.

Once Terraform has selected one or more resource instances that you've directly targeted, it will also then extend the selection to include all other objects that those selections depend on either directly or indirectly.

This targeting capability is provided for exceptional circumstances, such as recovering from mistakes or working around Terraform limitations.

Does -target work with Terraform count and for_each?

Yes. You can target individual instances using resource address syntax, such as -target='aws_instance.web[0]' for count or -target='aws_instance.web["prod"]' for for_each. Splat expressions like [*] are not supported, so wildcards across all instances are not allowed.

Targeting Syntax and Examples

Your Terraform configuration file usually defines multiple resources, such as an Azure Virtual Machine and an Azure Storage account.

You can use the -target option to specify a resource identifier.

To apply changes to your Azure Virtual Machine when defined in a module only and ignore all other resources, you can run terraform apply command with the -target option to reference the VM only:

terraform apply -target=module.vm.azurerm_linux_virtual_machine.example

In this command, the module is called vm, where the resource identifier is azurermlinuxvirtual_machine.example.

How to target a specific resource inside a module:

terraform apply -target=module.web_server.aws_instance.main

How to target an entire module:

terraform apply -target=module.web_server

How to target a specific module instance with count or for_each:

terraform apply -target='module.web_server[0]' terraform apply -target='module.web_server["prod"]'

Multiple targets can be specified with repeated -target flags:

terraform apply \ -target=aws_instance.web \ -target=aws_security_group.web \ -target=aws_eip.web

Each target is evaluated independently, and Terraform resolves dependencies between them.

To target multiple Terraform modules, use the -target flag with each module path explicitly defined during terraform apply or terraform plan.

terraform apply -target=module.network -target=module.database

To manage multiple modules more safely, structure your project with clear module boundaries and use workspaces or separate state files when isolation is required.

Targeting resources with terraform plan uses the same pattern as terraform apply, using the -target flag followed by the resource address.

terraform plan -target=aws_instance.web

The -target option works with terraform destroy as well, limiting destruction to the selected resources and their dependencies.

Dependency Resolution With Target

When you target a resource, Terraform also processes its dependencies.

Terraform also includes any resources that the targeted instance depends on, so its upstream prerequisites get planned and applied alongside it. Downstream resources that depend on the target are not automatically included, which is why partial applies often cause drift.

What happens to dependent resources when you use Terraform -target?

Terraform also includes any resources that the targeted instance depends on, so its upstream prerequisites get planned and applied alongside it. Downstream resources that depend on the target are not automatically included, which is why partial applies often cause drift.

How Dependency Resolution Works with -target:

When you target a resource, Terraform also processes its dependencies.

The practical impact is that a targeted change can pull in upstream data sources, provider configurations, and resources required for creation. It will not automatically update resources that consume the targeted resource's outputs. This asymmetry creates drift risk.

The reference materials note that targeting tells Terraform to focus on just part of the dependency graph. This can lead to partial updates, skipped changes, and long-term drift if you rely on it in routine workflows.

Target Versus Replace

What's the difference between Terraform -target and -replace?

The -target flag narrows a plan or apply to a specific resource and its dependencies, leaving everything else untouched. The -replace flag forces a chosen resource to be destroyed and recreated during a normal full-scope apply, without limiting which other resources Terraform evaluates.

-target limits scope. -replace forces recreation within full scope.

When To Use And Avoid Target

Targeting individual resources can be useful for troubleshooting errors, but should not be part of your normal workflow.

Appropriate exceptional situations include:

  • Recovering from mistakes
  • Working around Terraform limitations
  • State has become out of sync with your resources due to a network failure, a problem with the upstream cloud platform, or a bug in Terraform or its providers
  • One-off fixes
  • Accelerating changes in large deployments

The reference materials state that -target is handy for troubleshooting, one-off fixes, or accelerating changes in large deployments. It should not be used in routine workflows.

Avoid using -target as part of normal workflow because it leads to partial updates, skipped changes, and long-term drift. HashiCorp explicitly recommends using resource targeting only for exceptional situations, not as your default deployment strategy.

Without the -target option, the terraform plan, terraform apply or terraform destroy commands would take the entire configuration into account rather than a specific resource or set of Terraform resources.

Operational Considerations

The reference materials mention OpenTofu as an open-source version of Terraform that expands on Terraform's existing concepts and offerings. It is a viable alternative to HashiCorp's Terraform, being forked from Terraform version 1.5.6.

Orchestrate Terraform deployments with Spacelift. Orchestrate your Terraform workflows and build governed pipelines using policy as code, programmatic configuration, context sharing, drift detection, resource visualization, and many more.

Targeting affects plan output. A plan created with -target only shows changes for the selected resources and their dependencies. It does not show changes elsewhere in the configuration. Operators can mistakenly assume the plan represents the full state of the infrastructure.

Resource addressing requires exact syntax. For modules, the address is module.<name>.<resource_type>.<name>. For module instances with count or for_each, the address includes the index in quotes or brackets, such as module.web_server[0] or module.web_server["prod"].

Multiple -target flags are allowed. Each target is evaluated independently, and Terraform resolves dependencies between them.

Resource Address Selection Table

| Address Type | Example | Selection Behavior |
| Resource instance | aws_instance.web[0] | Selects that instance alone |
| Resource whole | aws_instance.web | Selects all instances of that resource, including all count/for_each indexes |
| Module instance | module.web_server | Selects all resources in that module and child modules |
| Module instance with index | module.web_server["prod"] | Selects that specific module instance |

Targeting Workflow Steps

  • Identify the exact resource address from state or configuration
  • Verify dependencies upstream and downstream before targeting
  • Run terraform plan -target=<address> to preview impact
  • Review which dependencies are included and which downstream resources are excluded
  • Execute terraform apply -target=<address> only for exceptional situations
  • Return to full-scope plan and apply to reconcile drift introduced by partial updates

Conclusion

Terraform target is a powerful but dangerous operator. It provides surgical control over plan, apply, and destroy operations by narrowing execution to a specific resource, module, or collection of resources. The mechanism extends selection to upstream dependencies but deliberately omits downstream consumers. That design makes it useful for isolated troubleshooting, for recovering from state desynchronization caused by network failures, upstream platform problems, or provider bugs, and for accelerating changes in large deployments where a full plan would be prohibitive.

The cost of that power is drift and partial updates. Because -target tells Terraform to focus on just part of the dependency graph, skipped changes accumulate when the same approach is used repeatedly. Upstream prerequisites are included, downstream dependents are not, which means outputs can become inconsistent with the rest of the infrastructure. HashiCorp explicitly recommends using resource targeting only for exceptional situations, not as your default deployment strategy. The reference materials repeat that targeting individual resources can be useful for troubleshooting errors, but should not be part of your normal workflow.

Correct usage requires precise address syntax, awareness of count and for_each indexing, and understanding of module boundaries. For resources with count or for_each, instance addresses must include the index. Splat expressions are not supported. Module addresses pull in all contained resources and child modules. Multiple -target flags can be combined, and each is evaluated independently with dependency resolution between them.

The difference between -target and -replace clarifies the intent. -target narrows scope; -replace forces recreation within full scope. Operators should prefer full-scope plans and applies for normal changes, reserve -target for exceptional recovery, and always follow a partial operation with a full-scope plan to detect and remediate drift.

Sources

  1. Spacelift Terraform Target Blog
  2. HashiCorp Terraform Targeting Tutorial
  3. OneUptime Terraform Apply Target Specific Resources
  4. HashiCorp Terraform CLI Plan Command

Related Posts