Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Document obtaining network information #11

Closed
bzub opened this issue Aug 23, 2017 · 6 comments
Closed

Document obtaining network information #11

bzub opened this issue Aug 23, 2017 · 6 comments

Comments

@bzub
Copy link
Contributor

bzub commented Aug 23, 2017

Affected Resource(s)

  • packet_device

References

https://www.terraform.io/docs/configuration/interpolation.html#user-map-variables
https://www.terraform.io/docs/configuration/interpolation.html#lookup-map-key-default-

Getting network information from packet_device.*.network is awkward due to limitations in Terraform around nested lists. Also, to get public/private/ipv4/ipv6 network elements you either have to assume the list is always ordered the same way (seems to work for me), or do complex lookups inside the nested list to verify values.

Maybe worth making the information available in a flat list or other, but for now I think obtaining for example the public ipv4 of a device should be documented.

Here's how I do it for public ipv4:

lookup(packet_device.test_device.network[0], "address")
@t0mk
Copy link
Contributor

t0mk commented Aug 23, 2017

I guess we could do it as they do it over at Digital Ocean:
https://github.com/terraform-providers/terraform-provider-digitalocean/blob/master/digitalocean/resource_digitalocean_droplet.go#L104

Not too hard to implement. But what to do when user assigns another public ipv4/ipv6 address to the device?

What do you mean by flat list?

@bzub
Copy link
Contributor Author

bzub commented Aug 23, 2017

Flat list as in a list of strings. I should have added that a map that's not in a list would be just as easy to use.

Without redundant output variables it's not really possible to represent all the information in the network objects and avoid nested lists, it seems to me. If that's accurate then we should probably document the data structure and how to use the lookup function to get network info. Beyond that, for convenience, we could copy the IPs into lists of strings with names like the digitalocean provider uses, so that additional IPs can be added or the user can just use the 0 index if they want to grab the initial IP.

Now that I've learned how the network objects are structured, and learned the ins/outs of Terraform interpolation syntax, I have no need for the convenience variables. I think it would be sufficient just to document the existing network data that is returned so other users don't have to do the same research.

@bzub
Copy link
Contributor Author

bzub commented Aug 27, 2017

TLDR: Changed my mind, we have to provide network info in a less-nested manner due to hashicorp/terraform#11036


I'll clarify and expand on this. I've found it's not possible to get network information from a group of packet_devices in TF without using a submodule to return the network info for each device. It's a long-standing known issue with no ETA to a fix.

For example, this is as far as one can get with a group of devices:

$ terraform console
> packet_device.controller.*.network
[
  [    {    address = 147.75.77.119  cidr = 31  family = 4  gateway = 147.75.77.118  public = 1},    {    address = 2604:1380:1:fd00::3  cidr = 127  family = 6  gateway = 2604:1380:1:fd00::2  public = 1},    {    address = 10.99.20.3  cidr = 31  family = 4  gateway = 10.99.20.2  public = 0}  ]
]
> packet_device.controller.*.network[0]
[
  {    address = 147.75.77.119  cidr = 31  family = 4  gateway = 147.75.77.118  public = 1},
  {    address = 2604:1380:1:fd00::3  cidr = 127  family = 6  gateway = 2604:1380:1:fd00::2  public = 1},
  {    address = 10.99.20.3  cidr = 31  family = 4  gateway = 10.99.20.2  public = 0}
]

I've tried everything to get access to the IPs in the network list. The only thing that works is to create a submodule that consumes the nested list and returns a list with one level of nesting removed.

Submodule: https://github.com/cloudnativelabs/kube-metal/tree/master/flatten
Usage: https://github.com/cloudnativelabs/kube-metal/blob/master/hosts.tf

$ terraform console
> module.all_networks.list
[
  {    address = 147.75.77.119  cidr = 31  family = 4  gateway = 147.75.77.118  public = 1},
  {    address = 2604:1380:1:fd00::3  cidr = 127  family = 6  gateway = 2604:1380:1:fd00::2  public = 1},
  {    address = 10.99.20.3  cidr = 31  family = 4  gateway = 10.99.20.2  public = 0},
  {    address = 147.75.78.59  cidr = 31  family = 4  gateway = 147.75.78.58  public = 1},
  {    address = 2604:1380:1:fd00::1  cidr = 127  family = 6  gateway = 2604:1380:1:fd00::  public = 1},
  {    address = 10.99.20.1  cidr = 31  family = 4  gateway = 10.99.20.0  public = 0}
]
> lookup(module.all_networks.list[0], "address")
147.75.77.119

@bzub
Copy link
Contributor Author

bzub commented Aug 27, 2017

So, how about replacing or supplementing the current network info schema with a lot of lists for each key in the network map?

> packet_device.example.*.ipv4_public_addresses[0]
[
  147.75.77.119
]
> element(packet_device.example.*.ipv4_public_addresses[0], 0)
147.75.77.119

So this would work when modules using this provider put count.index in the list index.

Same thing could be done for the rest of the variables in the network map.

  • ipv4_public_addresses, ipv6_public_addresses, ipv4_private_addresses
  • ipv4_public_cidrs, ipv6_public_cidrs, ipv4_private_cidrs
  • ipv4_public_gateways, ipv6_public_gateways, ipv4_private_gateways

It's still a little awkward since we'd have to explain that ipv4_public_* at a specified index are associated with one another.

@t0mk
Copy link
Contributor

t0mk commented Aug 28, 2017

Same thing could be done for the rest of the variables in the network map.

ipv4_public_addresses, ipv6_public_addresses, ipv4_private_addresses
ipv4_public_cidrs, ipv6_public_cidrs, ipv4_private_cidrs
ipv4_public_gateways, ipv6_public_gateways, ipv4_private_gateways

It's still a little awkward since we'd have to explain that ipv4_public_* at a specified index are associated with one another.

Unless this has been done in similar resource in another provider, I think this will not go through the review here.

What about following: Keep the network list as it is, and add 3 string fields to the device resource: access_public_ipv4, access_private_ipv4, access_public_ipv6? Just the address string would be there, no cidr, no gateway. Would this help your use-case?

This still obscures the assigned floating IPs, but we can say that externally assigned IPs can be accessed through the floating IP resources (which is still to come, but I am working on it). That's what they say in OpenStack and what they imply in the DigitalOcean resource linked above.

@bzub
Copy link
Contributor Author

bzub commented Aug 30, 2017

That works for me and probably most other use cases. If someone needs access to the extra network details I suppose we can point them to this issue for the workaround.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants