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:
- changing the underlying image of the droplets
- 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
More blog posts like this one
HashiCorp at re:Invent 2024: Infrastructure Lifecycle Management with AWS
A recap of HashiCorp infrastructure news and developments on AWS from the past year, from a new provider launch to simplifying infrastructure provisioning and more.
Simplify policy adoption in Terraform with pre-written Sentinel policies for AWS
HashiCorp introduces a new pre-written policy library co-developed with AWS, aiming to reduce the barrier of adoption for policy as code infrastructure workflows.
Terraform 1.10 improves handling secrets in state with ephemeral values
Terraform 1.10 is generally available, and it includes ephemeral values along with improvements to plan and apply performances.