Using self
in resource to reuse its name is currently impossible
resource "digitalocean_record" "mars" {
domain = "cyber.fund"
type = "A"
name = "${self.resource_name}"
value = "93.125.26.210"
}
Gives this error
* resource 'digitalocean_record.mars' config: cannot contain self-reference self.resource_name
Previous issues were closed without solution, of which self.resource_name
seems to be logical for everyone https://github.com/hashicorp/terraform/issues/925#issuecomment-237582442
Self reference for fields inside resource definition is hard, because it may produce infinite loop - https://github.com/hashicorp/terraform/commit/ae6bf241ec10b6d6eb01bb85a88b241855c19ffe#diff-2437af93acd4d73bd3a7a3fb1d4a38b6R9
But self.resource_name
is safe from infinite loops. Fixing it requires setting it somewhere, and lifting limitation on self reference for this specific case in https://github.com/hashicorp/terraform/blob/bbf9725134a75cc11661f5e2b316e8d81c1e05e4/config/config.go#L774 The updating the docs to include exceptional case https://www.terraform.io/docs/configuration/interpolation.html#attributes-of-your-own-resource
v0.10.7
As per current state of affairs , Is there a way to access the the in-line resource name from the plugin code , rather than defining a new "Name" attribute ?
It shouldn't be just the resource name. All non-dynamic attributes should be referenceable.
Example:
resource "aws_s3_bucket" "example_com" {
bucket = "example.com"
logging {
target_bucket = "logs.example.com"
target_prefix = "logs/${self.bucket}"
}
}
Thanks for this feature request @abitrolly, and sorry for the delay in responding.
We've discussed in some other issues the idea of adding a new meta
object that can be used to access metadata about various objects, like meta.aws_s3_bucket.example.created_time
or meta.self.created_time
, which would then avoid potential collisions with the actual data attributes of the resources. If we decided to implement this here then I think that's how we'd do it.
However, in general we are concerned about exposing the resource name in this way because there is a significant difference in scope between the resource name and the resource attributes: the resource's name is local to the current module, while the resource attributes are (in the normal case of a resource managing a remote object in some API) global.
While I can see some legitimate use-cases for it, like your example here of making the resource name match the DNS record name, ultimately I think that the extra complexity of having this feature and having to explain to users when it is and is not appropriate to use it outweighs the marginal benefit of matching the resource name with some attribute, especially once #17179 is implemented and it'd then be possible to use the _map key_ in expressions:
# not yet implemented, and details may change before release
locals {
dns_a_records = {
mars = "93.125.26.210"
}
}
resource "digitalocean_record" "a" {
for_each = local.dns_a_records
domain = "cyber.fund"
type = "A"
name = each.key
value = each.value
}
So with that said, unfortunately I think I'll have to say no to this request for now. I think the solution to #17179 will provide a way to reach a similar goal of avoiding repetition, but in a way which fits better within the language. For DNS in particular, I have a side project which is aiming to make use of both for_each
and other planned Terraform features to create modules that abstract over different DNS providers.
Thanks for sharing this suggestion and use-case. We're hoping that #17179 will be possible in the not-too-distant future because we're laying some groundwork for it as part of current work on the configuration language.
@jleclanche the idea of allowing self.
to reference resource attributes that are set explicitly in the config is a good one, and I agree that it'd be a useful addition. It's not currently compatible with how Terraform resolves expressions internally, but we may be able to add special handing for that situation in future. I think that's the same idea from the older issue #3267, so if you'd like to vote for that using the :+1: reaction on the initial comment we can use that as a signal in our planning process. I don't expect we'll be able to work on it in the very near future because there's already lots of other configuration-related work in progress for the next major release, but I agree it'd be very useful and would like to support it eventually.
Ref #8706 which wants more-or-less the same thing, and 💯 #17179 cannot come fast enough.
Even with a for_each
construct this feature would make sense, since it would let you do things like
for_each ${var.buckets} as ${bukkit} {
module "mah_bukkit" ${bukkit.value} {}
}
Refactoring that to use the module content directly in the for_each
would probably be better long-term, but it would be a much simpler transition if this feature were part of the existing module constructs.
Did anything change in 0.12 to allow referencing resource name inside its block?
I know, commenting on a closed issue has little value but I just wanted to add another use-case, per https://github.com/hashicorp/terraform/issues/16394#issuecomment-399210195, that I haven't seen mentioned: Tagging
resource provider_service_name resource_name {
...
tags = {
terraform_resource = meta.resource_address
}
...
}
where meta.resource_address
evaluates to provider_service_name.resource_name
.
Providing a set of standard tags has proven to be incredibly valuable for purposes of auditing, billing, and diagnostics, especially automated/computed values based on details not readily accessible in the deployed infrastructure.
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.
Most helpful comment
Did anything change in 0.12 to allow referencing resource name inside its block?