0.13 splat behavior

Current Terraform Version

Terraform v0.13.0-rc1

Use-cases

List IPs of droplets just created using a module with count.

Am unsure how to access the IPs once created using the module. I tried various different splat syntax from previous versions and receive empty tuple errors when trying to access the module.example-prod resource. Is this the right way to access this information?

Attempted Solutions

Full git repo.

Snippets for troubleshooting…

# infra/prod/main.tf
module "example-prod" {
    source = "../../modules/droplet"
    count  = 2

    droplet_name       = "tf-prod-${count.index + 1}"
    droplet_image      = var.droplet_image
    droplet_size       = var.droplet_size_1vcpu_1gb
    do_region          = var.do_region
    ssh_keys           = var.do_ssh_keys
}

The module:

# modules/droplet/main.tf
resource "digitalocean_droplet" "droplet" {
    name     = var.droplet_name
    image    = var.droplet_image
    size     = var.droplet_size
    region   = var.do_region
    ssh_keys = var.ssh_keys
}

Receive error thus:

  on main.tf line 13, in output "droplet_ips":
  13:     value = module.example-prod[*].digitalocean_droplet.droplet.ipv4_address

This object does not have an attribute named "digitalocean_droplet".

Hi @IronicBadger,

You have the correct splat operator syntax here, but I think the problem is that your module doesn’t have an output value called digitalocean_droplet. One way to make this work exactly as written would be to declare an output value in your module exporting that resource in its entirety:

output "digitalocean_droplet" {
  value = {
    droplet = digitalocean_droplet.droplet
  }
}

However, it’s more common to expose only a subset of resource data as an output, as part of creating a higher-level abstraction. If you want to do that, you could for example export just the IP address:

output "ipv4_address" {
  value = digitalocean_droplet.droplet.ipv4_address
}

That would then be accessible in the caller as module.example-prod[*].ipv4_address.

Or you could chose to expose an object containing the attributes of the droplet that the caller needs all as one value, like this:

output "vm" {
  value = {
    ipv4_address = digitalocean_droplet.droplet.ipv4_address
    # and anything else the caller needs
  }
}

That would then be accessible in the caller as module.example-prod[*].vm.ipv4_address.