Run terraform command with a specific resource
Terraform’s -target flag
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
, terraform apply
and also terraform destroy
. Resource Address syntax is used to specify the constraint. This targeting capability is provided for exceptional circumstances, such as recovering from mistakes or working around Terraform limitations.
For example, should we make changes but would only like to action the changes for the cloudwatch-to-zabix lambda function, we could write our plan command as follows:
/usr/local/src/terraform/terraform_0.12 plan -var-file=tfvars/prd.tfvars -state=./tfstate/terraform.tfstate.prd -target=aws_lambda_function.cloudwatch_to_zabbix_function -out run.plan
The plan result will be similar to:
------------------------------------------------------------------------
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:
# aws_lambda_function.cloudwatch_to_zabbix_function will be updated in-place
~ resource "aws_lambda_function" "cloudwatch_to_zabbix_function" {
arn = "arn:aws:lambda:ap-northeast-1:<account_id>:function:lambda-cloudwatch-to-zabbix"
filename = "lambda/upload/cloudwatch_to_zabbix_function.zip"
function_name = "lambda-cloudwatch-to-zabbix"
handler = "lambda_function.sender"
id = "lambda-cloudwatch-to-zabbix"
invoke_arn = "arn:aws:apigateway:<region>:lambda:path/<date/functions/arn:aws:lambda:<region>:<account_id>:function:lambda-cloudwatch-to-zabbix/invocations"
~ last_modified = "2020-05-12T07:19:02.273+0000" -> (known after apply)
layers = []
memory_size = 128
publish = false
qualified_arn = "arn:aws:lambda:<region>:<account_id>:function:lambda-cloudwatch-to-zabbix:$LATEST"
reserved_concurrent_executions = -1
role = "arn:aws:iam::<account_id>:role/sender-role"
runtime = "python3.7"
~ source_code_hash = "<hash>" -> "<hash>"
source_code_size = 8447
tags = {}
timeout = 3
version = "$LATEST"
environment {
variables = {
"HOST" = "cloudwatch"
"SERVER" = "example.com"
}
}
timeouts {}
tracing_config {
mode = "PassThrough"
}
vpc_config {
security_group_ids = [
"sg-0677xxxxxxx",
]
subnet_ids = [
"subnet-02xxxxxx",
"subnet-036xxxxxxx",
]
vpc_id = "vpc-0eb03f6xxxxx"
}
}
Plan: 0 to add, 1 to change, 0 to destroy.
Warning: Resource targeting is in effect
You are creating a plan with the -target option, which means that the result
of this plan may not represent all of the changes requested by the current
configuration.
The -target option is not for routine use, and is provided only for
exceptional situations such as recovering from errors or mistakes, or when
Terraform specifically suggests to use it as part of an error message.
------------------------------------------------------------------------
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 and specify the name of plan:
terraform apply run.plan
If you use the -target flag with terraform destroy command: instead of affecting “dependencies” will instead also destroy any resources that depend on the target(s) specified.
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.
Note:
1/ Resource Address syntax: is a string that references a specific resource in a larger infrastructure.
An address is made up of two parts:
[module path][resource spec]
Module path:
A module path addresses a module within the tree of modules. It takes the form:
module.A.module.B.module.C...
Resource spec:
A resource spec addresses a specific resource in the config. It takes the form:
resource_type.resource_name[resource index]
2/ 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. Instead of using -target
as a means to operate on isolated portions of very large configurations, prefer instead to break large configurations into several smaller configurations that can each be independently applied.
However, it is a feature of Terraform which you may be incredibly useful at some point in your infrastructure management workflow.
3/ You can use -target flag multiple times