-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better (any?) documentation for retrieving values from set data type #25717
Comments
Maybe another way to look at my question is, it seems like the set abstraction makes it difficult to do two things that used to be easy - condition a resource existence on a variable (in the |
I second this, Sets feel awkward to work with. |
Hi @kevinburkemeter, This change of type was a design tradeoff made by the AWS provider team, but based on what they wrote in the upgrade guide it seems like they were intending this as a response to the problem that there can potentially be more than one "validation option" and the remote API doesn't consider them to be ordered, and so referring to the "zeroth" one isn't a stable/meaningful idea. The upgrade guide also includes an example pattern for interacting with the new interface, which matches with some initial ideas I had after first reviewing your issue here. Here's an attempt at implementing the guidance from the upgrade guide in conjunction with what you showed in your comment (I'm not really familiar with this particular resource, so I'm working completely from the AWS provider docs here): resource "aws_route53_record" "root_validation" {
for_each = (var.https == "" || var.has_lb == false) ? {} : {
for dvo in aws_acm_certificate.root[0].domain_validation_options : dvo.domain_name => dvo
}
allow_overwrite = true
name = each.value.resource_record_name
records = [each.value.resource_record_value]
ttl = 60
type = each.value.resource_record_type
zone_id = data.aws_route53_zone.public_root_domain.zone_id
}
resource "aws_acm_certificate_validation" "root_validation" {
certificate_arn = aws_acm_certificate.root[0].arn
validation_record_fqdns = [for record in aws_route53_record.root_validation : record.fqdn]
} This would, assuming I'm understanding the As far as I can tell, the provider team made this design decision so that the provider's abstraction would match better with the remote system's abstraction, and so I'm not really sure how to generalize the above advice to all uses of sets: any time a provider team decides to use a set they are presumably doing so because that's the best fit for the design of the remote system, part of which includes there being no meaningful concept of "the first element" (because the items aren't ordered). When a provider uses a set to represent an unordered collection then, the typical intent is to do something with the entire set, rather than individual items from the set, but exactly what is intended will depend on the situation. It does seems like there is an opportunity here to factor out this particular combination of module "certificate" {
source = "some-organization/acm-certificate-with-route53/aws" # just a hypothetical; doesn't actually exist
count = (var.https == "" || var.has_lb == false) ? 0 : 1
route53_zone_id = aws_route53_record.www.zone_id
domain_name = aws_route53_record.www.name
subject_alternative_names = [
aws_route53_record.www.name,
aws_route53_zone.main.name,
]
} |
This comment was marked as off-topic.
This comment was marked as off-topic.
Hi @loganpowell, If what you are asking is how to write something like the example I showed above using the JSON version of the Terraform language, that seems like something better suited to the Terraform community forum. Thanks! |
@apparentlymart will do. Thank you! |
This comment was marked as off-topic.
This comment was marked as off-topic.
There does not appear to be a documentation change being requested here after #25717 (comment) -- closing this issue, but will re-open if I missed the outstanding request. |
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. |
The terraform-aws provider started using
sets
as output values in version 3, instead of lists or maps, so last night was my first experience using them. I have a set that has a single value in it. I would expect to be able to access this value using a key, or the[0]
index, or something. Instead, the only documentation resources I can see reference accessing the values in sets by iterating over all of them using thefor_each
operator.This is awkward in some places, like here (just as an example, don't worry about what this is actually doing)
I tried adding a
for_each
field but this interacts poorly with thecount
field - you can't have both - so I ended up doing this:Which also feels awkward.
I tried searching the Terraform documentation for information about the
set
datatype but found it lacking, particularly for how to get values out. There is this page, which explains that sets are unordered lists with no duplicates, but does not explain how to get values out of a set. https://www.terraform.io/docs/configuration/types.htmlContrast this with the list documentation - if I search Google for "terraform retrieve value from list" the answer is in both the first and third paragraphs of the top search result.
It would be useful to explain (if this is true? I don't know) that the only way to get values out of a set is to use the
for_each
operator and explain how to convert existing resources that might have acount
field like the one I have above.The text was updated successfully, but these errors were encountered: