Terraform: salida del módulo

Oct 30 2020

Tenemos tres espacios de trabajo en app.terraform.io,

  • PRUEBA
  • DEV
  • PRO

Esos espacios de trabajo tienen variables.

Obtengo el valor de con esas variables con ...

variable "environment" {}

Quiero usar esta variable para seleccionar qué recursos o módulos cargan.

resource "aws_directory_service_directory" "ds" {
  count = "${var.environment == "TEST" ? 0 : 1}"
  
  name       = "example.com"
  short_name = "example"
  password   = "******"
  type       = "MicrosoftAD"
}

Esto funciona pero ...

El resultado habitual de este recurso es ...

output id {
  description = "The ID of the directory"
  value       = aws_directory_service_directory.ds.id
}

output access_url {
  description = "The access URL for the directory"
  value       = aws_directory_service_directory.ds.access_url
}

output dns_ip_addresses {
  description = "A list of IP addresses of the DNS servers for the directory or connector"
  value       = aws_directory_service_directory.ds.dns_ip_addresses
}

output security_group_id {
  description = "The ID of the security group created by the directory"
  value       = aws_directory_service_directory.ds.security_group_id
}

Pero si uso el atributo count, la salida falla con ...

Because aws_directory_service_directory.ds has "count" set, its attributes
must be accessed on specific instances.

For example, to correlate with indices of a referring resource, use:
    aws_directory_service_directory.ds[count.index]

mixture of literal strings and interpolations. This deprecation applies only
to templates that consist entirely of a single interpolation sequence.


Error: Missing resource instance key

  on outputs.tf line 51, in output "security_group_id":
  51:   value       = aws_directory_service_directory.ds.security_group_id

Because aws_directory_service_directory.ds has "count" set, its attributes
must be accessed on specific instances.

For example, to correlate with indices of a referring resource, use:
    aws_directory_service_directory.ds[count.index]

¿Cuál sería la salida correcta?

Lo intenté:

output id {
  description = "The ID of the directory"
  value       = aws_directory_service_directory.ds[0].id
}

y:

output id {
  description = "The ID of the directory"
  value       = aws_directory_service_directory.ds[1].id
}

Pero no funciona (tampoco)

  on outputs.tf line 36, in output "id":
  36:   value       = aws_directory_service_directory.ds[0].id
    |----------------
    | aws_directory_service_directory.ds is empty tuple

The given key does not identify an element in this collection value.

Error: Invalid index

  on outputs.tf line 36, in output "id":
  36:   value       = aws_directory_service_directory.ds[1].id
    |----------------
    | aws_directory_service_directory.ds is tuple with 1 element

The given key does not identify an element in this collection value.

Traté de ver cómo se hace, por ejemplo https://github.com/terraform-aws-modules/terraform-aws-vpc

output "vpc_id" {
  description = "The ID of the VPC"
  value       = concat(aws_vpc.this.*.id, [""])[0]
}

entonces ...

output id {
  description = "The ID of the directory"
  value       = concat(aws_directory_service_directory.*.id, [""])[0]
}

pero ...

Error: Invalid reference

  on outputs.tf line 36, in output "id":
  36:   value       = concat(aws_directory_service_directory.*.id, [""])[0]

A reference to a resource type must be followed by at least one attribute
access, specifying the resource name.

Respuestas

3 BinaryMonster Oct 30 2020 at 09:49

Bueno, nada complejo, es solo que la salida busca el recurso que no se crea, ya que terraform todavía se refiere a ese recurso debido al cual arroja un error.

Si bien hay varias formas de abordar este problema, una de ellas es concatenar todos los recursos como lista en un paso y recuperar un solo elemento utilizando las funciones integradas de terraform.

Su salida debería ser algo como esto cuando está usando contar como condición para crear recursos. Si se crea el recurso, la salida será la identificación del recurso. Cuando el recuento es cero, la salida estará vacía sin errores.

output id {
  description = "The ID of the directory"
  value       = element(concat(aws_directory_service_directory.ds.*.id, list("")), 0)
}