terraform

Resource Targeting in Terraform

This guide exists for historical purposes, but a more up-to-date guide can be found here: Target Resources.

HashiCorp Terraform is a tool that uses code to define, provision and manage infrastructure. In a previous post, we looked at how you could seamlessly update virtual machines in your Terraform configuration without incurring downtime. In this post, we will discuss another feature of Terraform which can help you make fine grained changes, either to avoid downtime or recover from mistakes in your configuration resource targeting.

Consider the following example; you make two changes to the configuration:

  1. changing the underlying image of the droplets
  2. modify the health check of the load balancer

Should the first step fail, then you can not action the second change without first correcting any problems with the configuration. Ordinarily, this is the correct and recommended approach. However, a situation may exist where you require quick changes.

Another situation may be that a significant change is merged into your configuration, however rolling out the full change at present may not be desirable.

In both these cases, Terraform has a capacity which allows you to manage this exception by leveraging the resource targeting feature.

Resource targeting allows you to specify the -target option when you run terraform plan. An operator can specify one or more target options which contain a reference to resources in the configuration. When the plan runs, Terraform generates a plan only containing these resources.

Terraform interprets the resource address passed with the target option as follows:

  • If the given address has a resource spec, only the specified resource is targeted. If the named resource uses count and no explicit index is specified in the address, all of the instances sharing the given resource name are targeted.
  • The the given address does not have a resource spec, and instead specifies a module path, the target applies to all resources in the specified module and all of the descendent modules of the specified module.

For example, should we make changes to digitalocean_droplet.web and digitalocean_loadbalancer.public but would only like to action the changes for the load balancer we could write our plan command as follows:

$ terraform plan -target digitalocean_loadbalancer.public -out run.plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

digitalocean_loadbalancer.public: Refreshing state... (ID: 37548666-99f6-4619-ad18-f53d42385064)

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  ~ digitalocean_loadbalancer.public
      forwarding_rule.0.target_port: "80" => "8080"


Plan: 0 to add, 1 to change, 0 to destroy.

------------------------------------------------------------------------

This plan was saved to: run.plan

To perform exactly these actions, run the following command to apply:
    terraform apply "run.plan"

Terraform has now generated a plan which only includes the targeted resource. We can apply the plan in the normal with terraform apply.

$ terraform apply run.plan
digitalocean_loadbalancer.public: Modifying... (ID: 37548666-99f6-4619-ad18-f53d42385064)
  forwarding_rule.0.target_port: "80" => "8080"
digitalocean_loadbalancer.public: Modifications complete after 2s (ID: 37548666-99f6-4619-ad18-f53d42385064)

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Outputs:

lb_ip = 159.65.211.49

Using targeted resources is this way has allowed us to process any urgent changes without having to execute the entire plan or modify the configuration.

»Summary

The targeting capability is provided for exceptional circumstances, such as recovering from mistakes or working around Terraform limitations. It is not recommended to use -target for routine operations since this can lead to undetected configuration drift and confusion about how the actual state of resources relates to the configuration.

Targeting is, however, a feature of Terraform which you may be incredibly useful at some point in your infrastructure management workflow, it is a useful feature to know as you never know when you may need it.


Sign up for the latest HashiCorp news

By submitting this form, you acknowledge and agree that HashiCorp will process your personal information in accordance with the Privacy Policy.