BernalCarlos
BernalCarlos

Reputation: 1006

Terraform resource as a module input variable

When developing a terraform module, I sometimes find myself in the need to define different input variables for the same resources. For example, right now I need the NAME and ARN of the same AWS/ECS cluster for my module, so, I defined two variables in my module: ecs_cluster_arn and ecs_cluster_name.

For the sake of DRY, it would be very nice if I could just define the input variable ecs_cluster of type aws_ecs_cluster and the just use whatever I need inside my module.

I can't seem to find a way to do this. Does anyone know if it's possible?

Upvotes: 3

Views: 3261

Answers (1)

Martin Atkins
Martin Atkins

Reputation: 74654

You can define an input variable whose type constraint is compatible with the schema of the aws_ecs_cluster resource type. Typically you'd write a subset type constraint that contains only the attributes the module actually needs. For example:

variable "ecs_cluster" {
  type = object({
    name = string
    arn  = string
  })
}

Elsewhere in the module, you can use var.ecs_cluster.name and var.ecs_cluster.arn to refer to those attributes. The caller of the module can pass in anything that's compatible with that type constraint, which includes a whole instance of the aws_ecs_cluster resource type, but would also include a literal object containing just those two attributes:

module "example" {
  # ...

  ecs_cluster = aws_ecs_cluster.example
}
module "example" {
  # ...

  ecs_cluster = {
    name = "blah"
    arn  = "arn:aws:yada-yada:blah"
  }
}

In many cases this would also allow passing the result of the corresponding data source instead of the managed resource type. Unfortunately for this pairing in particular the data source for some reason uses the different attribute name cluster_name and therefore isn't compatible. That's unfortunate, and not the typical design convention for pairs of managed resource type and data source with the same name; I assume it was a design oversight.

module "example" {
  # ...

  # This doesn't actually work for the aws_ecs_cluster
  # data source because of a design quirk, but this would
  # be possible for most other pairings such as
  # the aws_subnet managed resource type and data source.
  ecs_cluster = data.aws_ecs_cluster.example
}

Upvotes: 4

Related Questions