Conditionals in terraform

if I have several modules, I have a module to create fargate instances.

Suppose, I want to select with resource should be created.

resource “aws_ecs_task_definition” “ldap” {

count = var.com_mont ? 1 : 0
(…)
}

but below i have :
some thing like

task_definition = aws_ecs_task_definition.ldap.arn

and when i execute tterraform apply it does not work properly

###Error message#

on …\source\modulos\fargate\main.tf line 142, in resource “aws_ecs_service” “main”:
142: task_definition = aws_ecs_task_definition.ldap.arn

Because aws_ecs_task_definition.ldap has “count” set, its attributes must be
accessed on specific instances.

##############

how can i fix this issue, or i can not use conditionals like this way ?

thanks a lot and best regards

Hi @jose.pinto,

There are a few different ways to proceed here. The main root thing is that you’ll need to decide what ought to happen to the downstream resources (those that depend on the task definition) when the task definition isn’t enabled.

I’m rusty on ECS but if I’m remembering correctly it doesn’t make sense to have an ECS service without a task definition, so probably in this case you’d want to apply a conditional count to the service resource too:

resource "aws_ecs_service" "main" {
  count = length(aws_ecs_task_definition.ldap)

  task_definition = aws_ecs_task_definition.ldap[count.index].arn
}

The above says that there should be the same number of ECS services as there are task definitions (by your current declaration of the task definition, either zero or one) and that each service should take its task definition from the corresponding instance of aws_ecs_task_definition.ldap.

In other situations the more appropriate thing to do would be to keep the downstream resource itself unconditional but to make one of its arguments literal. I don’t think that really make sense in the situation you’re describing, but I want to mention it for completeness in case you run into other situations like this later:

resource "aws_ecs_service" "main" {
  # ...
  task_definition = (
    length(aws_ecs_task_definition.ldap) > 0 ? aws_ecs_task_definition.ldap[0] : null
  )
}

The above sets task_definition to null in the case where there are no task definitions, while keeping the ECS service resource. Setting a resource argument to null is the same as not setting it at all, so this would be appropriate only for an optional argument, and so I expect this would fail for task_definition which IIRC is a required argument of aws_ecs_service.

it is an example, in this case, I have used a ECS service, but could be another.

Even in ECS you can have.

Real case scenario:

take a look at this requirement, you have created your ECS modules with task definition, ok

Requirents: use only a farget module ( with tas defenition etc)

ECS1: this ecs does not havew volumes
ECS2: this ecs needs a volumes

So mai fatgate mudule will be like this:

( pseudo code)

if ECS1 tehsn call resourece "resource “aws_ecs_task_definition” , with valome defenition

if ECS, resource “aws_ecs_task_definition” without volumes defenition.

i have tried using the same but issues occur.

So I am going to use a different resource “aws_ecs_task_definition”

So I would like to use something like this ( pseudocode)

if ( create a task with volumes)

“call task definition with volumes”

else
“call task definition without volumes”

I want to avoid create different terraform modules only because some requirements are not used.

unfortunately does not work properly:

##############
Error: Reference to “count” in non-counted context

2021-03-01T17:14:52.242Z [DEBUG] plugin: plugin process exited: path=.terraform/providers/registry.terraform.io/hashicorp/aws/3.29.1/windows_amd64/terraform-provider-aws_v3.29.1_x5.exe pid=16052
2021-03-01T17:14:52.242Z [DEBUG] plugin: plugin exited
on …..\source\modulos\fargate\main.tf line 142, in resource “aws_ecs_service” “main”:
142: task_definition = aws_ecs_task_definition.ldap[count.index].arn

The “count” object can only be used in “module”, “resource”, and “data”
blocks, and only when the “count” argument is set.

do you know how can i fix it ?

i have checked the issue, missing: missing the count after the resource with the arn.

thanks a lot, i have closed an important requirement ( use less modules as possible)
this is is my requirements, i would like write terraform code, most clean as possible.

resource “aws_ecs_task_definition” “ldap” {

count = “${var.nometaskdefenitionsem_mont ? 1 : 0}”