Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform AWS Provider: array of ECS task placement constraints?

I'm using terraform 0.10.7 and AWS Terraform provider version 1.7.

In my terraform for creating an ECS task, I would like to be able to use multiple ECS placement constraints. Looking through the Terraform documentation, I see only examples of using a single constraint, but everything seems to indicate that this is possible. (Example: https://github.com/terraform-providers/terraform-provider-aws/blob/e77ce9a5fca5b2a3e1138f5df86e87170ac8e89a/aws/resource_aws_ecs_task_definition.go)

My most recent attempt looks like:

resource "aws_ecs_task_definition" "task" {
  family                = "${var.service_name}"
  container_definitions = "${var.container_definitions}"
  task_role_arn         = "${var.task_role_arn}"
  placement_constraints {
    count = "${var.placement_constraint_count}"
    type = "memberOf"
    expression = "${element(var.placement_constraints, count.index)}"
  }
}

In the passed-in tfvars, I have various things declared, including:

var.placement_constraint_count = 1
var.placement_constraints = [ "attribute:adsk.max-container-disk-space-gb not_exists or attribute:adsk.max-container-disk-space-gb == 100"]

(It's a custom attribute, not relevant to the problem at hand.)

This results in: * Errors: [placement_constraints.0: invalid or unknown key: count]

Looking through the Go source code for the schema of a placement constraint (https://github.com/terraform-providers/terraform-provider-aws/blob/e77ce9a5fca5b2a3e1138f5df86e87170ac8e89a/aws/resource_aws_ecs_task_definition.go) - it's a TypeSet with a maximum of 10 elements, each of which has a 'type' and an 'expression'.

So... what's the proper way to say all that?

Thanks,

Dave

like image 809
David Watt Avatar asked Feb 21 '18 08:02

David Watt


1 Answers

Clarification

I ran up your Terraform snippet in my sandbox just now to check things out, and the given error is sound if a little terse:

Error: aws_ecs_task_definition.task: placement_constraints.0: invalid or unknown key: count

The reality is that placement_constraint does not support a count attribute.

Taking the count line out of the placement_constraint block stopped the error from occurring.

The schema in the code you linked only specifies type and expression, and there is no allowance for count.

Defining multiple constraints requires multiple instances of the placement_constraint block in the Terraform template.

Alternative suggestion

For your purposes, I would use something along these lines:

terraform.tfvars

placement_constraints = [
  "attribute:one == 1",
  "attribute:two == 2",
  "attribute:three == 3",
]

ecs_task.tf

resource "aws_ecs_task_definition" "task" {
  container_definitions = "${var.container_definitions}"
  family                = "${var.service_name}"
  task_role_arn         = "${var.task_role_arn}"

  placement_constraints {
    expression = "${element(var.placement_constraints, 0)}"
    type       = "memberOf"
  }

  placement_constraints {
    expression = "${element(var.placement_constraints, 1)}"
    type       = "memberOf"
  }

  placement_constraints {
    expression = "${element(var.placement_constraints, 2)}"
    type       = "memberOf"
  }
}

Yes, it is repetitive and ugly.

No, Terraform is not a feature-complete v1.0 tool just yet. 😔

I run into limitations like this one all the time with my clients and projects.

On the plus side, the upcoming for and for-each loops in v0.12 should help with situations like this.

Hope that helps!


I ran all of this with the following from terraform version:

Terraform v0.11.7
+ provider.aws v1.28.0
like image 128
jlucktay Avatar answered Oct 17 '22 15:10

jlucktay