Terraform: We should be able to query if an attribute was created or not for a resource.

Created on 31 Aug 2017  ยท  6Comments  ยท  Source: hashicorp/terraform

Hi there,

Terraform Version

Terraform v0.10.0

Hello fellow terraformer! I have been trying for a while to update a variable based on the allocation of a resource. and I can't figure out how to tell Terraform to ignore attribute reference when they don't exist.
For example, I have a resource which could expose the attribute ipv4_address_private; for this attribute to exist it seems that I need to set the config private_networking to true when creating the resource. (digitalocean_droplet resource). Now I want to basically use the private IPv4 when it exists or else fall back to the attribute ipv4_address which is the public IP.
The problem is that I haven't been able to find a way to detect that the following attribute doesn't exist.
digitalocean_droplet.registry.ipv4_address_private

I was thinking of doing something like
value = coalesce(digitalocean_droplet.registry.ipv4_address_private, digitalocean_droplet.registry.ipv4_address) expecting an empty string for the first entry
but terraform throws the error : Resource 'digitalocean_droplet.registry' does not have attribute 'ipv4_address_private' for variable 'digitalocean_droplet.registry.ipv4_address_private'

Is there any way of querying the attribute to know in advance if terraform created them or not ?

I'm using this in a template file to set variables

data "template_file" "postinstall" {
  template = "${file("${path.module}/../../postinstall/postinstall.sh")}"

  vars {
ips = "${join(",", concat(coalesce(digitalocean_droplet.saltmaster.ipv4_address_private, digitalocean_droplet.saltmaster.ipv4_address),
                              coalesce(digitalocean_droplet.registry.ipv4_address_private, digitalocean_droplet.registry.ipv4_address) ))}"


}
config enhancement

Most helpful comment

The new configuration language implementation we're currently working on integrating will expose ipv4_address_private as null when it isn't set, so if we update coalesce to treat null the same as the empty string (and I don't see any reason why we couldn't do that) then I think we'd get the desired behavior here.

All 6 comments

after digging in the provider code, I saw that the property doesn't get created when the private_network is false.
https://github.com/terraform-providers/terraform-provider-digitalocean/blob/master/digitalocean/resource_digitalocean_droplet.go#L300-L303

I'm not sure though if the ReadLogic is executed within the same execution of the create command. Or if the prpoerty would be read from an intermediate step/caching Since I'm creating the template within the same execution of terraform apply where the droplet is also created.

Note that I'm keeping this issue under Core until I know more of the expected default behavior for Terraform with property/attribute.

In other works should all attribute be queryable even if not set or present ?

Ran into this recently, where using a resource means that you can't always output its value, if the attribute doesn't exist (ie when the resource didn't get created).

At a higher level, we would need for a way to check, via interpolation, if the attribute exists, then use it if it does. It would be great if methods like coalesce could do this natively.

The new configuration language implementation we're currently working on integrating will expose ipv4_address_private as null when it isn't set, so if we update coalesce to treat null the same as the empty string (and I don't see any reason why we couldn't do that) then I think we'd get the desired behavior here.

To follow up on @apparentlymart's comment: in Terraform 0.12, coalesce treats null the same way it treats empty strings. Here's a silly example to show how this works now:

$ cat main.tf
variable "thing1" {
  type = string
  default = ""
}

variable "thing2" {
  type = string
  default = null
}

variable "thing3" {
  type = string
  default = "string"
}


output "coalesce" {
  value = coalesce(var.thing1, var.thing2, var.thing3)
}
$ terraform output
coalesce = string

I am going to close this issue now. Thank you!

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings