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 and remove resources as proposed by the plan.
In a typical Terraform workflow, you apply the entire plan at once. Occasionally you may want to only apply part of a plan, such as situations where Terraform's 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. To support this, Terraform allows you to target specific resources when you plan, apply, or destroy your infrastructure. Targeting individual resources can be useful for troubleshooting errors, but should not be part of your normal workflow.
You can use Terraform's -target
option to target specific resources, modules,
or collections of resources. In this tutorial, you will provision an S3 bucket
with some objects in it, then apply changes incrementally with -target
.
»Prerequisites
In order to follow this tutorial, you will need:
- The Terraform CLI, version 0.14 or later.
- AWS Credentials configured for use with Terraform.
- The git CLI.
Note: Some of the infrastructure in this tutorial may not qualify for the AWS free tier. Destroy the infrastructure at the end of the tutorial to avoid unnecessary charges. We are not responsible for any charges that you incur.
»Create infrastructure
The example configuration for this tutorial is hosted in a GitHub repository. This configuration defines an S3 bucket with a randomized name, and four S3 bucket objects.
Clone the repository.
$ git clone https://github.com/hashicorp/learn-terraform-resource-targeting.git
$ git clone https://github.com/hashicorp/learn-terraform-resource-targeting.git
Navigate to the repository directory.
$ cd learn-terraform-resource-targeting
$ cd learn-terraform-resource-targeting
Initialize your Terraform project.
$ terraform init
$ terraform init
Apply this configuration to create your S3 bucket and objects.
$ terraform apply An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_s3_bucket_object.objects[0] will be created + resource "aws_s3_bucket_object" "objects" { + acl = "public-read" + bucket = (known after apply) ##... Plan: 11 to add, 0 to change, 0 to destroy. Changes to Outputs: + bucket_arn = (known after apply) + bucket_name = (known after apply) Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes random_pet.bucket_name: Creating... random_pet.object_names[2]: Creating... random_pet.object_names[3]: Creating... random_pet.object_names[1]: Creating... random_pet.object_names[0]: Creating... ##... aws_s3_bucket_object.objects[1]: Still creating... [10s elapsed] aws_s3_bucket_object.objects[1]: Creation complete after 12s [id=learning_partially_eminently_intensely_elegant_worm.txt] Apply complete! Resources: 11 added, 0 changed, 0 destroyed. Outputs: bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn" bucket_name = "learning-specially-tender-fawn"
$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_s3_bucket_object.objects[0] will be created
+ resource "aws_s3_bucket_object" "objects" {
+ acl = "public-read"
+ bucket = (known after apply)
##...
Plan: 11 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ bucket_arn = (known after apply)
+ bucket_name = (known after apply)
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
random_pet.bucket_name: Creating...
random_pet.object_names[2]: Creating...
random_pet.object_names[3]: Creating...
random_pet.object_names[1]: Creating...
random_pet.object_names[0]: Creating...
##...
aws_s3_bucket_object.objects[1]: Still creating... [10s elapsed]
aws_s3_bucket_object.objects[1]: Creation complete after 12s [id=learning_partially_eminently_intensely_elegant_worm.txt]
Apply complete! Resources: 11 added, 0 changed, 0 destroyed.
Outputs:
bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn"
bucket_name = "learning-specially-tender-fawn"
Confirm by typing yes
at the prompt.
»Target the S3 bucket name
In main.tf
, find the random_pet.bucket_name
resource. The bucket module uses this resource to assign a randomized name to the S3 bucket. Update the value of length
to 5
.
resource "random_pet" "bucket_name" { - length = 3 + length = 5 separator = "-" prefix = "learning" }
resource "random_pet" "bucket_name" {
- length = 3
+ length = 5
separator = "-"
prefix = "learning"
}
Plan this change.
$ terraform plan random_pet.object_names[1]: Refreshing state... [id=learning_partially_eminently_intensely_elegant_worm] random_pet.object_names[3]: Refreshing state... [id=learning_rationally_lately_slowly_careful_warthog] ##... An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: -/+ destroy and then create replacement Terraform will perform the following actions: # aws_s3_bucket_object.objects[0] must be replaced -/+ resource "aws_s3_bucket_object" "objects" { ~ bucket = "learning-specially-tender-fawn" -> (known after apply) # forces replacement ~ etag = "542494210de74912127de19a3acece21" -> (known after apply) ##... # module.s3_bucket.aws_s3_bucket_public_access_block.this[0] must be replaced -/+ resource "aws_s3_bucket_public_access_block" "this" { ~ bucket = "learning-specially-tender-fawn" -> (known after apply) # forces replacement ~ id = "learning-specially-tender-fawn" -> (known after apply) # (4 unchanged attributes hidden) } Plan: 7 to add, 0 to change, 7 to destroy. Changes to Outputs: ~ bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn" -> (known after apply) ~ bucket_name = "learning-specially-tender-fawn" -> (known after apply) ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
$ terraform plan
random_pet.object_names[1]: Refreshing state... [id=learning_partially_eminently_intensely_elegant_worm]
random_pet.object_names[3]: Refreshing state... [id=learning_rationally_lately_slowly_careful_warthog]
##...
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# aws_s3_bucket_object.objects[0] must be replaced
-/+ resource "aws_s3_bucket_object" "objects" {
~ bucket = "learning-specially-tender-fawn" -> (known after apply) # forces replacement
~ etag = "542494210de74912127de19a3acece21" -> (known after apply)
##...
# module.s3_bucket.aws_s3_bucket_public_access_block.this[0] must be replaced
-/+ resource "aws_s3_bucket_public_access_block" "this" {
~ bucket = "learning-specially-tender-fawn" -> (known after apply) # forces replacement
~ id = "learning-specially-tender-fawn" -> (known after apply)
# (4 unchanged attributes hidden)
}
Plan: 7 to add, 0 to change, 7 to destroy.
Changes to Outputs:
~ bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn" -> (known after apply)
~ bucket_name = "learning-specially-tender-fawn" -> (known after apply)
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Notice how Terraform plans to change the random_pet
resource along with any
resources dependent on it.
Tip: To change the bucket's name, Terraform must replace the bucket. AWS does not support renaming buckets in place. The AWS provider understands this, and Terraform creates a plan that will replace or update your resources as needed.
Plan the change again, but only target the random_pet.bucket_name
resource.
$ terraform plan -target="random_pet.bucket_name" random_pet.bucket_name: Refreshing state... [id=learning-specially-tender-fawn] An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: -/+ destroy and then create replacement Terraform will perform the following actions: # random_pet.bucket_name must be replaced -/+ resource "random_pet" "bucket_name" { ~ id = "learning-specially-tender-fawn" -> (known after apply) ~ length = 3 -> 5 # forces replacement # (2 unchanged attributes hidden) } Plan: 1 to add, 0 to change, 1 to destroy. Changes to Outputs: ~ bucket_name = "learning-specially-tender-fawn" -> (known after apply) Warning: Resource targeting is in effect ##...
$ terraform plan -target="random_pet.bucket_name"
random_pet.bucket_name: Refreshing state... [id=learning-specially-tender-fawn]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# random_pet.bucket_name must be replaced
-/+ resource "random_pet" "bucket_name" {
~ id = "learning-specially-tender-fawn" -> (known after apply)
~ length = 3 -> 5 # forces replacement
# (2 unchanged attributes hidden)
}
Plan: 1 to add, 0 to change, 1 to destroy.
Changes to Outputs:
~ bucket_name = "learning-specially-tender-fawn" -> (known after apply)
Warning: Resource targeting is in effect
##...
Terraform will only plan to replace the targeted resource.
You can also target modules — Terraform will apply the change to all resources in the module. Target the S3 bucket module.
$ terraform plan -target="module.s3_bucket" random_pet.bucket_name: Refreshing state... [id=learning-specially-tender-fawn] module.s3_bucket.aws_s3_bucket.this[0]: Refreshing state... [id=learning-specially-tender-fawn] module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Refreshing state... [id=learning-specially-tender-fawn] An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: -/+ destroy and then create replacement Terraform will perform the following actions: # random_pet.bucket_name must be replaced -/+ resource "random_pet" "bucket_name" { ~ id = "learning-specially-tender-fawn" -> (known after apply) ~ length = 3 -> 5 # forces replacement # (2 unchanged attributes hidden) } # module.s3_bucket.aws_s3_bucket.this[0] must be replaced -/+ resource "aws_s3_bucket" "this" { + acceleration_status = (known after apply) ~ arn = "arn:aws:s3:::learning-specially-tender-fawn" -> (known after apply) ~ bucket = "learning-specially-tender-fawn" -> (known after apply) # forces replacement ~ bucket_domain_name = "learning-specially-tender-fawn.s3.amazonaws.com" -> (known after apply) ~ bucket_regional_domain_name = "learning-specially-tender-fawn.s3.eu-west-1.amazonaws.com" -> (known after apply) ~ hosted_zone_id = "Z1BKCTXD74EZPE" -> (known after apply) ~ id = "learning-specially-tender-fawn" -> (known after apply) ~ region = "eu-west-1" -> (known after apply) ~ request_payer = "BucketOwner" -> (known after apply) - tags = {} -> null + website_domain = (known after apply) + website_endpoint = (known after apply) # (2 unchanged attributes hidden) ~ versioning { ~ enabled = false -> (known after apply) ~ mfa_delete = false -> (known after apply) } } # module.s3_bucket.aws_s3_bucket_public_access_block.this[0] must be replaced -/+ resource "aws_s3_bucket_public_access_block" "this" { ~ bucket = "learning-specially-tender-fawn" -> (known after apply) # forces replacement ~ id = "learning-specially-tender-fawn" -> (known after apply) # (4 unchanged attributes hidden) } Plan: 3 to add, 0 to change, 3 to destroy. Changes to Outputs: ~ bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn" -> (known after apply) ~ bucket_name = "learning-specially-tender-fawn" -> (known after apply) Warning: Resource targeting is in effect ##...
$ terraform plan -target="module.s3_bucket"
random_pet.bucket_name: Refreshing state... [id=learning-specially-tender-fawn]
module.s3_bucket.aws_s3_bucket.this[0]: Refreshing state... [id=learning-specially-tender-fawn]
module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Refreshing state... [id=learning-specially-tender-fawn]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# random_pet.bucket_name must be replaced
-/+ resource "random_pet" "bucket_name" {
~ id = "learning-specially-tender-fawn" -> (known after apply)
~ length = 3 -> 5 # forces replacement
# (2 unchanged attributes hidden)
}
# module.s3_bucket.aws_s3_bucket.this[0] must be replaced
-/+ resource "aws_s3_bucket" "this" {
+ acceleration_status = (known after apply)
~ arn = "arn:aws:s3:::learning-specially-tender-fawn" -> (known after apply)
~ bucket = "learning-specially-tender-fawn" -> (known after apply) # forces replacement
~ bucket_domain_name = "learning-specially-tender-fawn.s3.amazonaws.com" -> (known after apply)
~ bucket_regional_domain_name = "learning-specially-tender-fawn.s3.eu-west-1.amazonaws.com" -> (known after apply)
~ hosted_zone_id = "Z1BKCTXD74EZPE" -> (known after apply)
~ id = "learning-specially-tender-fawn" -> (known after apply)
~ region = "eu-west-1" -> (known after apply)
~ request_payer = "BucketOwner" -> (known after apply)
- tags = {} -> null
+ website_domain = (known after apply)
+ website_endpoint = (known after apply)
# (2 unchanged attributes hidden)
~ versioning {
~ enabled = false -> (known after apply)
~ mfa_delete = false -> (known after apply)
}
}
# module.s3_bucket.aws_s3_bucket_public_access_block.this[0] must be replaced
-/+ resource "aws_s3_bucket_public_access_block" "this" {
~ bucket = "learning-specially-tender-fawn" -> (known after apply) # forces replacement
~ id = "learning-specially-tender-fawn" -> (known after apply)
# (4 unchanged attributes hidden)
}
Plan: 3 to add, 0 to change, 3 to destroy.
Changes to Outputs:
~ bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn" -> (known after apply)
~ bucket_name = "learning-specially-tender-fawn" -> (known after apply)
Warning: Resource targeting is in effect
##...
Terraform notices that module.s3_bucket
depends on random_pet.bucket_name
,
and that the bucket name configuration has changed. As a result, it will plan
updates to both the resources inside the module and the bucket name resource so
that the directly targeted resources match the current configuration, including
dependencies. Resource targeting updates resources that the targeted resource
depends on, but not resources that depend on it.
Note: Terraform creates a dependency graph to determine the correct order in which to apply changes. You can read more about how it works in the Terraform documentation.
Apply the change to only the bucket name. Respond to the confirmation prompt
with yes
.
$ terraform apply -target="random_pet.bucket_name" random_pet.bucket_name: Refreshing state... [id=learning-specially-tender-fawn] An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: -/+ destroy and then create replacement Terraform will perform the following actions: # random_pet.bucket_name must be replaced -/+ resource "random_pet" "bucket_name" { ~ id = "learning-specially-tender-fawn" -> (known after apply) ~ length = 3 -> 5 # forces replacement # (2 unchanged attributes hidden) } Plan: 1 to add, 0 to change, 1 to destroy. Changes to Outputs: ~ bucket_name = "learning-specially-tender-fawn" -> (known after apply) Warning: Resource targeting is in effect ##... Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes random_pet.bucket_name: Destroying... [id=learning-specially-tender-fawn] random_pet.bucket_name: Destruction complete after 0s random_pet.bucket_name: Creating... random_pet.bucket_name: Creation complete after 0s [id=learning-optionally-violently-apparently-equal-skylark] Warning: Applied changes may be incomplete The plan was created with the -target option in effect, so some changes requested in the configuration may have been ignored and the output values may not be fully updated. Run the following command to verify that no other changes are pending: terraform plan Note that the -target option is not suitable 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. Apply complete! Resources: 1 added, 0 changed, 1 destroyed. Outputs: bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn" bucket_name = "learning-optionally-violently-apparently-equal-skylark"
$ terraform apply -target="random_pet.bucket_name"
random_pet.bucket_name: Refreshing state... [id=learning-specially-tender-fawn]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# random_pet.bucket_name must be replaced
-/+ resource "random_pet" "bucket_name" {
~ id = "learning-specially-tender-fawn" -> (known after apply)
~ length = 3 -> 5 # forces replacement
# (2 unchanged attributes hidden)
}
Plan: 1 to add, 0 to change, 1 to destroy.
Changes to Outputs:
~ bucket_name = "learning-specially-tender-fawn" -> (known after apply)
Warning: Resource targeting is in effect
##...
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
random_pet.bucket_name: Destroying... [id=learning-specially-tender-fawn]
random_pet.bucket_name: Destruction complete after 0s
random_pet.bucket_name: Creating...
random_pet.bucket_name: Creation complete after 0s [id=learning-optionally-violently-apparently-equal-skylark]
Warning: Applied changes may be incomplete
The plan was created with the -target option in effect, so some changes
requested in the configuration may have been ignored and the output values may
not be fully updated. Run the following command to verify that no other
changes are pending:
terraform plan
Note that the -target option is not suitable 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.
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
Outputs:
bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn"
bucket_name = "learning-optionally-violently-apparently-equal-skylark"
Notice that the bucket_name
output changes, and no longer matches the bucket
ARN. Open outputs.tf
and notice that the bucket name value is derived from the
random pet resource, instead of the bucket itself.
output "bucket_name" { description = "Randomly generated bucket name." value = random_pet.bucket_name.id }
output "bucket_name" {
description = "Randomly generated bucket name."
value = random_pet.bucket_name.id
}
When using Terraform's normal workflow, this would not matter since your change would apply to the resource and its dependent resources. But since you targeted the random pet resource, the output changed while the bucket name did not. Targeting resources can make your state inconsistent, which is part of why you should only use it in troubleshooting scenarios.
Update the output to refer to the bucket name directly.
output "bucket_name" { description = "Randomly generated bucket name." - value = random_pet.bucket_name.id + value = module.s3_bucket.s3_bucket_id }
output "bucket_name" {
description = "Randomly generated bucket name."
- value = random_pet.bucket_name.id
+ value = module.s3_bucket.s3_bucket_id
}
Because you have only targeted part of your configuration the last time you
applied your changes, the resources you have provisioned do not match either the
original configuration or the new configuration. Apply the entire change, and
Terraform will provision your infrastructure to match your configuration, as
well as update the bucket_name
output.
$ terraform apply random_pet.object_names[1]: Refreshing state... [id=learning_partially_eminently_intensely_elegant_worm] random_pet.bucket_name: Refreshing state... [id=learning-optionally-violently-apparently-equal-skylark] random_pet.object_names[2]: Refreshing state... [id=learning_brightly_strangely_naturally_willing_aardvark] random_pet.object_names[3]: Refreshing state... [id=learning_rationally_lately_slowly_careful_warthog] random_pet.object_names[0]: Refreshing state... [id=learning_firmly_smoothly_firmly_dashing_bonefish] ##... Plan: 6 to add, 0 to change, 6 to destroy. Changes to Outputs: ~ bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn" -> (known after apply) ~ bucket_name = "learning-optionally-violently-apparently-equal-skylark" -> (known after apply) Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Destroying... [id=learning-specially-tender-fawn] aws_s3_bucket_object.objects[0]: Destroying... [id=learning_firmly_smoothly_firmly_dashing_bonefish.txt] aws_s3_bucket_object.objects[3]: Destroying... [id=learning_rationally_lately_slowly_careful_warthog.txt] aws_s3_bucket_object.objects[2]: Destroying... [id=learning_brightly_strangely_naturally_willing_aardvark.txt] aws_s3_bucket_object.objects[1]: Destroying... [id=learning_partially_eminently_intensely_elegant_worm.txt] ##... aws_s3_bucket_object.objects[2]: Creation complete after 7s [id=learning_brightly_strangely_naturally_willing_aardvark.txt] aws_s3_bucket_object.objects[1]: Creation complete after 7s [id=learning_partially_eminently_intensely_elegant_worm.txt] aws_s3_bucket_object.objects[3]: Creation complete after 7s [id=learning_rationally_lately_slowly_careful_warthog.txt] aws_s3_bucket_object.objects[0]: Creation complete after 7s [id=learning_firmly_smoothly_firmly_dashing_bonefish.txt] Apply complete! Resources: 6 added, 0 changed, 6 destroyed. Outputs: bucket_arn = "arn:aws:s3:::learning-optionally-violently-apparently-equal-skylark" bucket_name = "learning-optionally-violently-apparently-equal-skylark"
$ terraform apply
random_pet.object_names[1]: Refreshing state... [id=learning_partially_eminently_intensely_elegant_worm]
random_pet.bucket_name: Refreshing state... [id=learning-optionally-violently-apparently-equal-skylark]
random_pet.object_names[2]: Refreshing state... [id=learning_brightly_strangely_naturally_willing_aardvark]
random_pet.object_names[3]: Refreshing state... [id=learning_rationally_lately_slowly_careful_warthog]
random_pet.object_names[0]: Refreshing state... [id=learning_firmly_smoothly_firmly_dashing_bonefish]
##...
Plan: 6 to add, 0 to change, 6 to destroy.
Changes to Outputs:
~ bucket_arn = "arn:aws:s3:::learning-specially-tender-fawn" -> (known after apply)
~ bucket_name = "learning-optionally-violently-apparently-equal-skylark" -> (known after apply)
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Destroying... [id=learning-specially-tender-fawn]
aws_s3_bucket_object.objects[0]: Destroying... [id=learning_firmly_smoothly_firmly_dashing_bonefish.txt]
aws_s3_bucket_object.objects[3]: Destroying... [id=learning_rationally_lately_slowly_careful_warthog.txt]
aws_s3_bucket_object.objects[2]: Destroying... [id=learning_brightly_strangely_naturally_willing_aardvark.txt]
aws_s3_bucket_object.objects[1]: Destroying... [id=learning_partially_eminently_intensely_elegant_worm.txt]
##...
aws_s3_bucket_object.objects[2]: Creation complete after 7s [id=learning_brightly_strangely_naturally_willing_aardvark.txt]
aws_s3_bucket_object.objects[1]: Creation complete after 7s [id=learning_partially_eminently_intensely_elegant_worm.txt]
aws_s3_bucket_object.objects[3]: Creation complete after 7s [id=learning_rationally_lately_slowly_careful_warthog.txt]
aws_s3_bucket_object.objects[0]: Creation complete after 7s [id=learning_firmly_smoothly_firmly_dashing_bonefish.txt]
Apply complete! Resources: 6 added, 0 changed, 6 destroyed.
Outputs:
bucket_arn = "arn:aws:s3:::learning-optionally-violently-apparently-equal-skylark"
bucket_name = "learning-optionally-violently-apparently-equal-skylark"
Confirm this change by typing yes
at the prompt.
After using resource targeting to fix problems with a Terraform project, be sure
to apply the entire change so that your project's state and configuration are
consistent with the resources you are managing with Terraform. Remember that you
can use terraform plan
to see what changes have yet to be applied.
»Target specific bucket objects
Open main.tf
and update the contents of the bucket objects. The example
configuration uses a single line of example text to represent objects with
useful data in them. Change the bucket contents as shown below.
resource "aws_s3_bucket_object" "objects" { count = 4 acl = "public-read" key = "${random_pet.object_names[count.index].id}.txt" bucket = module.s3_bucket.s3_bucket_id - content = "Example object #${count.index}" + content = "Bucket object #${count.index}" content_type = "text/plain" }
resource "aws_s3_bucket_object" "objects" {
count = 4
acl = "public-read"
key = "${random_pet.object_names[count.index].id}.txt"
bucket = module.s3_bucket.s3_bucket_id
- content = "Example object #${count.index}"
+ content = "Bucket object #${count.index}"
content_type = "text/plain"
}
You can use the -target
option multiple times to target several resources at
once. Apply this change to two of the bucket objects. Confirm with a yes
.
$ terraform apply -target="aws_s3_bucket_object.objects[2]" -target="aws_s3_bucket_object.objects[3]" random_pet.object_names[1]: Refreshing state... [id=learning_partially_eminently_intensely_elegant_worm] random_pet.bucket_name: Refreshing state... [id=learning-optionally-violently-apparently-equal-skylark] random_pet.object_names[0]: Refreshing state... [id=learning_firmly_smoothly_firmly_dashing_bonefish] random_pet.object_names[3]: Refreshing state... [id=learning_rationally_lately_slowly_careful_warthog] random_pet.object_names[2]: Refreshing state... [id=learning_brightly_strangely_naturally_willing_aardvark] ##... Terraform will perform the following actions: # aws_s3_bucket_object.objects[2] will be updated in-place ~ resource "aws_s3_bucket_object" "objects" { ~ content = "Example object #2" -> "Bucket object #2" id = "learning_brightly_strangely_naturally_willing_aardvark.txt" tags = {} + version_id = (known after apply) # (8 unchanged attributes hidden) } # aws_s3_bucket_object.objects[3] will be updated in-place ~ resource "aws_s3_bucket_object" "objects" { ~ content = "Example object #3" -> "Bucket object #3" id = "learning_rationally_lately_slowly_careful_warthog.txt" tags = {} + version_id = (known after apply) # (8 unchanged attributes hidden) } Plan: 0 to add, 2 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. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_s3_bucket_object.objects[2]: Modifying... [id=learning_brightly_strangely_naturally_willing_aardvark.txt] aws_s3_bucket_object.objects[3]: Modifying... [id=learning_rationally_lately_slowly_careful_warthog.txt] aws_s3_bucket_object.objects[3]: Modifications complete after 7s [id=learning_rationally_lately_slowly_careful_warthog.txt] aws_s3_bucket_object.objects[2]: Modifications complete after 7s [id=learning_brightly_strangely_naturally_willing_aardvark.txt] Warning: Applied changes may be incomplete The plan was created with the -target option in effect, so some changes requested in the configuration may have been ignored and the output values may not be fully updated. Run the following command to verify that no other changes are pending: terraform plan Note that the -target option is not suitable 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. Apply complete! Resources: 0 added, 2 changed, 0 destroyed. Outputs: bucket_arn = "arn:aws:s3:::learning-optionally-violently-apparently-equal-skylark" bucket_name = "learning-optionally-violently-apparently-equal-skylark"
$ terraform apply -target="aws_s3_bucket_object.objects[2]" -target="aws_s3_bucket_object.objects[3]"
random_pet.object_names[1]: Refreshing state... [id=learning_partially_eminently_intensely_elegant_worm]
random_pet.bucket_name: Refreshing state... [id=learning-optionally-violently-apparently-equal-skylark]
random_pet.object_names[0]: Refreshing state... [id=learning_firmly_smoothly_firmly_dashing_bonefish]
random_pet.object_names[3]: Refreshing state... [id=learning_rationally_lately_slowly_careful_warthog]
random_pet.object_names[2]: Refreshing state... [id=learning_brightly_strangely_naturally_willing_aardvark]
##...
Terraform will perform the following actions:
# aws_s3_bucket_object.objects[2] will be updated in-place
~ resource "aws_s3_bucket_object" "objects" {
~ content = "Example object #2" -> "Bucket object #2"
id = "learning_brightly_strangely_naturally_willing_aardvark.txt"
tags = {}
+ version_id = (known after apply)
# (8 unchanged attributes hidden)
}
# aws_s3_bucket_object.objects[3] will be updated in-place
~ resource "aws_s3_bucket_object" "objects" {
~ content = "Example object #3" -> "Bucket object #3"
id = "learning_rationally_lately_slowly_careful_warthog.txt"
tags = {}
+ version_id = (known after apply)
# (8 unchanged attributes hidden)
}
Plan: 0 to add, 2 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.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_s3_bucket_object.objects[2]: Modifying... [id=learning_brightly_strangely_naturally_willing_aardvark.txt]
aws_s3_bucket_object.objects[3]: Modifying... [id=learning_rationally_lately_slowly_careful_warthog.txt]
aws_s3_bucket_object.objects[3]: Modifications complete after 7s [id=learning_rationally_lately_slowly_careful_warthog.txt]
aws_s3_bucket_object.objects[2]: Modifications complete after 7s [id=learning_brightly_strangely_naturally_willing_aardvark.txt]
Warning: Applied changes may be incomplete
The plan was created with the -target option in effect, so some changes
requested in the configuration may have been ignored and the output values may
not be fully updated. Run the following command to verify that no other
changes are pending:
terraform plan
Note that the -target option is not suitable 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.
Apply complete! Resources: 0 added, 2 changed, 0 destroyed.
Outputs:
bucket_arn = "arn:aws:s3:::learning-optionally-violently-apparently-equal-skylark"
bucket_name = "learning-optionally-violently-apparently-equal-skylark"
Notice in the output that Terraform has only updated the contents of buckets 2 and 3.
»Target bucket object names
As shown above, you can target individual instances from a
collection created with count
or for_each
. However, Terraform calculates
resource dependencies for the entire resource. In some cases, this can lead to
surprising results.
Remove the prefix
argument from the random_pet.object_names
resource in
main.tf
.
resource "random_pet" "object_names" { count = 4 length = 5 separator = "_" - prefix = "learning" }
resource "random_pet" "object_names" {
count = 4
length = 5
separator = "_"
- prefix = "learning"
}
Attempt to apply this change to a single bucket object.
$ terraform apply -target="aws_s3_bucket_object.objects[2]" random_pet.object_names[2]: Refreshing state... [id=learning_brightly_strangely_naturally_willing_aardvark] random_pet.object_names[3]: Refreshing state... [id=learning_rationally_lately_slowly_careful_warthog] random_pet.bucket_name: Refreshing state... [id=learning-optionally-violently-apparently-equal-skylark] random_pet.object_names[1]: Refreshing state... [id=learning_partially_eminently_intensely_elegant_worm] random_pet.object_names[0]: Refreshing state... [id=learning_firmly_smoothly_firmly_dashing_bonefish] ##... Terraform will perform the following actions: # aws_s3_bucket_object.objects[2] must be replaced -/+ resource "aws_s3_bucket_object" "objects" { ~ etag = "ac6265d2157e71b8e8470b465ddb45db" -> (known after apply) ~ id = "learning_brightly_strangely_naturally_willing_aardvark.txt" -> (known after apply) ~ key = "learning_brightly_strangely_naturally_willing_aardvark.txt" -> (known after apply) # forces replacement + kms_key_id = (known after apply) - metadata = {} -> null + server_side_encryption = (known after apply) ~ storage_class = "STANDARD" -> (known after apply) - tags = {} -> null + version_id = (known after apply) # (5 unchanged attributes hidden) } # random_pet.object_names[0] must be replaced -/+ resource "random_pet" "object_names" { ~ id = "learning_firmly_smoothly_firmly_dashing_bonefish" -> (known after apply) - prefix = "learning" -> null # forces replacement # (2 unchanged attributes hidden) } # random_pet.object_names[1] must be replaced -/+ resource "random_pet" "object_names" { ~ id = "learning_partially_eminently_intensely_elegant_worm" -> (known after apply) - prefix = "learning" -> null # forces replacement # (2 unchanged attributes hidden) } # random_pet.object_names[2] must be replaced -/+ resource "random_pet" "object_names" { ~ id = "learning_brightly_strangely_naturally_willing_aardvark" -> (known after apply) - prefix = "learning" -> null # forces replacement # (2 unchanged attributes hidden) } # random_pet.object_names[3] must be replaced -/+ resource "random_pet" "object_names" { ~ id = "learning_rationally_lately_slowly_careful_warthog" -> (known after apply) - prefix = "learning" -> null # forces replacement # (2 unchanged attributes hidden) } Plan: 5 to add, 0 to change, 5 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. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value:
$ terraform apply -target="aws_s3_bucket_object.objects[2]"
random_pet.object_names[2]: Refreshing state... [id=learning_brightly_strangely_naturally_willing_aardvark]
random_pet.object_names[3]: Refreshing state... [id=learning_rationally_lately_slowly_careful_warthog]
random_pet.bucket_name: Refreshing state... [id=learning-optionally-violently-apparently-equal-skylark]
random_pet.object_names[1]: Refreshing state... [id=learning_partially_eminently_intensely_elegant_worm]
random_pet.object_names[0]: Refreshing state... [id=learning_firmly_smoothly_firmly_dashing_bonefish]
##...
Terraform will perform the following actions:
# aws_s3_bucket_object.objects[2] must be replaced
-/+ resource "aws_s3_bucket_object" "objects" {
~ etag = "ac6265d2157e71b8e8470b465ddb45db" -> (known after apply)
~ id = "learning_brightly_strangely_naturally_willing_aardvark.txt" -> (known after apply)
~ key = "learning_brightly_strangely_naturally_willing_aardvark.txt" -> (known after apply) # forces replacement
+ kms_key_id = (known after apply)
- metadata = {} -> null
+ server_side_encryption = (known after apply)
~ storage_class = "STANDARD" -> (known after apply)
- tags = {} -> null
+ version_id = (known after apply)
# (5 unchanged attributes hidden)
}
# random_pet.object_names[0] must be replaced
-/+ resource "random_pet" "object_names" {
~ id = "learning_firmly_smoothly_firmly_dashing_bonefish" -> (known after apply)
- prefix = "learning" -> null # forces replacement
# (2 unchanged attributes hidden)
}
# random_pet.object_names[1] must be replaced
-/+ resource "random_pet" "object_names" {
~ id = "learning_partially_eminently_intensely_elegant_worm" -> (known after apply)
- prefix = "learning" -> null # forces replacement
# (2 unchanged attributes hidden)
}
# random_pet.object_names[2] must be replaced
-/+ resource "random_pet" "object_names" {
~ id = "learning_brightly_strangely_naturally_willing_aardvark" -> (known after apply)
- prefix = "learning" -> null # forces replacement
# (2 unchanged attributes hidden)
}
# random_pet.object_names[3] must be replaced
-/+ resource "random_pet" "object_names" {
~ id = "learning_rationally_lately_slowly_careful_warthog" -> (known after apply)
- prefix = "learning" -> null # forces replacement
# (2 unchanged attributes hidden)
}
Plan: 5 to add, 0 to change, 5 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.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
Notice that Terraform updated all five of the names, not just the name of the
object you targeted. Both resources use count
to provision multiple copies,
and each bucket object refers to the corresponding name. However, because the
entire aws_s3_bucket_objects.objects
resource depends on the entire
random_pet.object_names
resource Terraform updated all the names.
Accept the change with a yes
.
Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_s3_bucket_object.objects[2]: Destroying... [id=learning_brightly_strangely_naturally_willing_aardvark.txt] aws_s3_bucket_object.objects[2]: Destruction complete after 1s random_pet.object_names[2]: Destroying... [id=learning_brightly_strangely_naturally_willing_aardvark] ##... Apply complete! Resources: 5 added, 0 changed, 5 destroyed. Outputs: bucket_arn = "arn:aws:s3:::learning-optionally-violently-apparently-equal-skylark" bucket_name = "learning-optionally-violently-apparently-equal-skylark"
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_s3_bucket_object.objects[2]: Destroying... [id=learning_brightly_strangely_naturally_willing_aardvark.txt]
aws_s3_bucket_object.objects[2]: Destruction complete after 1s
random_pet.object_names[2]: Destroying... [id=learning_brightly_strangely_naturally_willing_aardvark]
##...
Apply complete! Resources: 5 added, 0 changed, 5 destroyed.
Outputs:
bucket_arn = "arn:aws:s3:::learning-optionally-violently-apparently-equal-skylark"
bucket_name = "learning-optionally-violently-apparently-equal-skylark"
»Destroy your infrastructure
Terraform's destroy command also accepts resource targeting. In the examples
above, you referred to individual bucket objects with brackets, such as
aws_s3_bucket_object.objects[2]
. You can also refer to the entire collection
of resources at once. Destroy the bucket objects, and respond to the
confirmation prompt with a yes
.
$ terraform destroy -target="aws_s3_bucket_object.objects" An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # aws_s3_bucket_object.objects[0] will be destroyed - resource "aws_s3_bucket_object" "objects" { - acl = "public-read" -> null - bucket = "learning-optionally-violently-apparently-equal-skylark" -> null ##... Plan: 0 to add, 0 to change, 4 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. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes aws_s3_bucket_object.objects[3]: Destroying... [id=learning_rationally_lately_slowly_careful_warthog.txt] aws_s3_bucket_object.objects[1]: Destroying... [id=learning_partially_eminently_intensely_elegant_worm.txt] aws_s3_bucket_object.objects[2]: Destroying... [id=mostly_manually_certainly_cheerful_quetzal.txt] aws_s3_bucket_object.objects[0]: Destroying... [id=learning_firmly_smoothly_firmly_dashing_bonefish.txt] aws_s3_bucket_object.objects[2]: Destruction complete after 1s aws_s3_bucket_object.objects[3]: Destruction complete after 1s aws_s3_bucket_object.objects[0]: Destruction complete after 1s aws_s3_bucket_object.objects[1]: Destruction complete after 1s Warning: Applied changes may be incomplete The plan was created with the -target option in effect, so some changes requested in the configuration may have been ignored and the output values may not be fully updated. Run the following command to verify that no other changes are pending: terraform plan Note that the -target option is not suitable 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. Destroy complete! Resources: 4 destroyed.
$ terraform destroy -target="aws_s3_bucket_object.objects"
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_s3_bucket_object.objects[0] will be destroyed
- resource "aws_s3_bucket_object" "objects" {
- acl = "public-read" -> null
- bucket = "learning-optionally-violently-apparently-equal-skylark" -> null
##...
Plan: 0 to add, 0 to change, 4 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.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_s3_bucket_object.objects[3]: Destroying... [id=learning_rationally_lately_slowly_careful_warthog.txt]
aws_s3_bucket_object.objects[1]: Destroying... [id=learning_partially_eminently_intensely_elegant_worm.txt]
aws_s3_bucket_object.objects[2]: Destroying... [id=mostly_manually_certainly_cheerful_quetzal.txt]
aws_s3_bucket_object.objects[0]: Destroying... [id=learning_firmly_smoothly_firmly_dashing_bonefish.txt]
aws_s3_bucket_object.objects[2]: Destruction complete after 1s
aws_s3_bucket_object.objects[3]: Destruction complete after 1s
aws_s3_bucket_object.objects[0]: Destruction complete after 1s
aws_s3_bucket_object.objects[1]: Destruction complete after 1s
Warning: Applied changes may be incomplete
The plan was created with the -target option in effect, so some changes
requested in the configuration may have been ignored and the output values may
not be fully updated. Run the following command to verify that no other
changes are pending:
terraform plan
Note that the -target option is not suitable 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.
Destroy complete! Resources: 4 destroyed.
Now destroy the rest of your infrastructure. Respond to the confirmation prompt
with yes
.
$ terraform destroy
$ terraform destroy
»Next steps
In this tutorial, you used Terraform's resource targeting to specify which resources to apply a given change to. Resource targeting is a useful tool in some contexts, but you should avoid using it in day to day operations, as it can cause your infrastructure to become inconsistent.
- Read the Terraform documentation for resource targeting.
- Follow our Manage Resources in Terraform State tutorial to learn about other ways to manipulate Terraform state.
- Follow our Separate Development and Production Environments tutorial to learn how to organize your Terraform projects.