Targeting a specific resource in Terraform is more than just a shortcut; it’s a way to precisely control the blast radius of your infrastructure changes.

Let’s see it in action. Imagine you have a main.tf file defining a VPC and a single EC2 instance within it:

provider "aws" {
  region = "us-east-1"
}

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "main-vpc"
  }
}

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0" # Example AMI, use a current one
  instance_type = "t2.micro"
  vpc_security_group_ids = [aws_security_group.web.id]
  subnet_id = aws_subnet.public.id

  tags = {
    Name = "HelloWorldWebServer"
  }
}

resource "aws_security_group" "web" {
  name        = "web-sg"
  description = "Allow SSH and HTTP inbound traffic"
  vpc_id      = aws_vpc.main.id

  ingress {
    description = "SSH from anywhere"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "HTTP from anywhere"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "web-sg"
  }
}

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
  map_public_ip_on_launch = true
  availability_zone = "us-east-1a"

  tags = {
    Name = "public-subnet"
  }
}

Now, let’s say you want to update the instance_type of aws_instance.web_server to t2.medium without touching the VPC or security group. You’d run:

terraform plan -target=aws_instance.web_server

This command tells Terraform to only consider the aws_instance.web_server resource when planning. The output will show a plan to modify only that instance. When you apply this plan:

terraform apply

Only the EC2 instance will be updated. The VPC and security group remain untouched.

The core problem targeting solves is reducing the risk and complexity of infrastructure changes. In large, interconnected environments, a full terraform apply can be daunting, potentially impacting many services. Targeting allows you to isolate a change to a single resource or a small, related group of resources. This is crucial for:

  • Rapid Iteration: Quickly update a specific resource without waiting for a full plan/apply cycle.
  • Minimizing Downtime: Apply changes to a single component that can be updated independently, avoiding cascading failures.
  • Debugging: Isolate an issue by applying specific changes to pinpoint the cause.
  • Staged Rollouts: Gradually introduce changes to a subset of your infrastructure.

Internally, when you use -target, Terraform builds its dependency graph as usual, but then it filters that graph, keeping only the specified resource and any resources it depends on. It will not include resources that depend on the targeted resource unless they are also explicitly targeted. This ensures that your change doesn’t inadvertently affect other parts of your infrastructure that aren’t directly related to the targeted resource’s direct dependencies.

The resource_type.resource_name format is the key. For aws_instance.web_server, aws_instance is the resource type and web_server is the resource name as defined in your .tf files. You can target modules too, using module.module_name.

It’s important to understand that -target only affects the plan and apply operations. terraform destroy will still destroy all resources managed by the state file, regardless of targeting. If you want to destroy only a targeted resource, you’d typically use terraform destroy -target=aws_instance.web_server (though this is often discouraged for complex environments due to potential state file inconsistencies if not managed carefully).

The most surprising thing about -target is that it doesn’t just plan for the targeted resource; it plans for all resources that the targeted resource depends on. So, if you target aws_instance.web_server, Terraform will also include the aws_vpc and aws_security_group in the plan because the instance cannot exist without them. It will not, however, include the aws_subnet in the plan if the instance doesn’t directly depend on it, even though they are in the same VPC. This dependency-aware filtering is what makes targeting safe and predictable.

The next conceptual hurdle you’ll face is understanding how to effectively manage state when using -target for destructive operations or when dealing with complex inter-resource dependencies.

Want structured learning?

Take the full Terraform course →