Terraform-provider-aws: Exported value aws_vpc_endpoint_service of aws_vpc_endpoint_service has no indices

Created on 17 Sep 2020  路  8Comments  路  Source: hashicorp/terraform-provider-aws

Community Note

  • Please vote on this issue by adding a 馃憤 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform CLI and Terraform AWS Provider Version

$ terraform -v
Terraform v0.13.2

  • provider registry.terraform.io/hashicorp/aws v3.6.0

Affected Resource(s)

aws_vpc_endpoint_service, exporting single indexed value of base_endpoint_dns_names

Terraform Configuration Files

output "endpointinfo" {
  value = aws_vpc_endpoint_service.epsvc.base_endpoint_dns_names.0
}

Debug Output

https://gist.github.com/tezzigator/42966402f94d12bc8eef573f37c595f2

Expected Behavior

Expected to see the leading string of that list output

Actual Behavior

Error: Invalid index

  on modules/workload/main.tf line 202, in output "endpointinfo":
 202:   value = aws_vpc_endpoint_service.epsvc.base_endpoint_dns_names.0

This value does not have any indices.

Important Factoids

If I simply export the entire aws_vpc_endpoint_service then I do get an actual list:

orangeendpointsvc = [
  "vpce-svc-REDACTED.us-east-1.vpce.amazonaws.com",
]

But that comma there concerns me - seems like it shouldnt be there; I supposed that could be causing all this?

  • #0000
documentation good first issue question servicec2

All 8 comments

base_endpoint_dns_names is a set (an unordered collection) so it can't be indexed. If you want to use an index, you can call tolist():

output "endpointinfo" {
  value = tolist(aws_vpc_endpoint_service.epsvc.base_endpoint_dns_names)[0]
}

I would caution you that it's safer to process all names returned in whatever code is using the output. Your particular example is returning a single end point, but since it's a set that's not guaranteed behavior.

@tezzigator Thanks for raising this.
As you suspect, the underlying cause is mis-documentation of the dns_names attribute as "list" rather than "set".
There are many other such related issues (just a sample):

  • #12487
  • #11636
  • #11738
  • #10273
  • #10147
  • #9733
  • #9381

@ewbankkit I don't see base_endpoint_dns_names documented as a list or a set explicitly. I agree the documentation should be better about showing the expected types though.

I'd like to contribute to this, is there any concensus on the best way to handle this? I think I can work around the problem by adding a code example using tolist () to the documentation about base_endpoint_dns_names.

I'm not sure it's recommended to do so, so I'm not sure the documentation should include that as an example. Generally, if an item is a set, it means the ordering isn't relevant or guaranteed from the API. So converting it to a list and processing items by an index can result in unnecessary resource modification/recreation if the ordering changes. I think the recommended way to process a set is with the for_each directive.

More specifically in the use case here, the user may be assuming that there's only a single name to process and is trying to index into the set to get access to that name as a string. While that may be a way to meet their goal at a tactical level, I don't think it's a strategy that should be encouraged as it's fragile.

Would a valid solution be to make it standard to include the type being returned in the docs under Attributes Reference?
eg:


Attributes Reference

In addition to all arguments above, the following attributes are exported:

  • acceptance_required - bool - Whether or not VPC endpoint connection requests to the service must be accepted by the service owner - true or false.
  • arn - string - The Amazon Resource Name (ARN) of the VPC endpoint service.
  • availability_zones - list(string) - The Availability Zones in which the service is available.

    * base_endpoint_dns_names - set(string) - The DNS names for the service.

Personally I'd like that. I feel like it would be good if it was a terraform wide standard change, so I'm not sure what the protocol is for changing the format just in the AWS provider. But I've had more than one occasion where I've had to lookup the return type because it's not obvious, so I think this is desirable.

I agree. I think it is desirable that the return type is documented.

Was this page helpful?
0 / 5 - 0 ratings