Taint a resource created with for_each

I am creating a number of ECS services like this:

resource "aws_ecs_service" "service" {
  for_each = toset(var.cluster_names)

  name          = "${var.repository}_${var.group}_${var.service_name}"
  cluster       = "${each.key}"
  desired_count = "${var.desired_count}"

  ordered_placement_strategy {
    type  = "spread"
    field = "instanceId"
  }

  ordered_placement_strategy {
    type  = "spread"
    field = "attribute:ecs.availability-zone"
  }

  load_balancer {
    container_name   = "${var.service_name}"
    container_port   = "${var.port}"
    target_group_arn = "${var.target_group_arn}"
  }

  # Track the latest ACTIVE revision
  task_definition = "${aws_ecs_task_definition.task_def.family}:${max("${aws_ecs_task_definition.task_def.revision}", "${data.aws_ecs_task_definition.task_def.revision}")}"

}

How do I taint the resources created this way?

The following don’t work
terraform taint aws_ece_service.service
terraform taint aws_ece_service.service.*
terraform taint aws_ece_service.service[]
terraform taint aws_ece_service.service

I believe the splats only work with lists and for_each returns a map. Not sure how to reference elements in the map…

Try for example,

aws_ece_service.service["a_cluster"]

To refer to one of the resource instances associated with a resource block the syntax is

<TYPE>.<NAME>[<KEY>]

Seemed so promising but no go:

terraform taint module.servotron.aws_ecs_service.service["FrontEnd-OnDemand"]

Yields

Error: Index value required

on line 1:
(source code not available)

Index brackets must contain either a literal number or a literal string.

Run ‘terraform state list’ to see how each resource is identified by terraform.

Awesome. That indeed shows that I was using the right syntax. taint must just be broken for this scenario.

I will log a bug against terraform.

Did you get anywhere with this issue?

Hi @outthought!

That is indeed the correct index syntax for a for_each resource instance. A gotcha with it is that quotes are often interpreted by your shell, so some form of escaping would be needed.

In a Unix-style shell we can use single quotes around the whole address to mark the quotes as literal:

terraform taint 'aws_ece_service.service["a_cluster"]'

On Windows systems, single quotes are not a conventional way to mark literals so we must use backslash escapes instead:

terraform taint aws_ece_service.service[\"a_cluster\"]

Without that escaping, the value will often be received by Terraform with some sort of corruption, like aws_ece_service.service[a_cluster], which then leads to a parse error in Terraform.