terraform-provider-triton
terraform-provider-triton copied to clipboard
Specifying specific IP of instance in Fabric network when creating instance
From what I understand it is possible to specify a specific IP at instance creation (I assume this is only possible in a FabricNetwork which you own). This assumption is based on what I read in the CloudAPI documentation.
As far as I can tell neither the NodeJS triton tool nor this Terraform provider allows one to actually do this. I might be interested in implementing this. It is mainly useful for applications which assume their IP's stay the same when redeployed (looking at you LeoFS).
What would be the preferred config syntax for Terraform? The CloudAPI itself allows it to be specified in the networks tag with a ipv4_ips object.
Hi @siepkes! This would likely be a useful feature to support. The ideal way to do this would be to break out networks into configuration maps instead of treating them as strings, so you could do something like this:
resource "triton_machine" "name" {
# ....
network {
id = "network UUID"
ip = "172.21.1.42"
}
network {
id = "network UUID"
}
}
This would however be a breaking change, and we should likely think through alternatives. @stack72, any thoughts here?
It seems newer versions of the CloudAPI also started making a distinction between IP versions. Since the IP is called ipv4_ips and the network uuid not simply uuid but ipv4_uuid. Might be a good idea to keep that in mind when we devise a config syntax.
I don't know what the intention is in regards to Terraform config syntax design; Keep the Terraform config syntax as close as possible to the Cloud API or does is the Terraform config syntax fully abstract the CloudAPI design?
Is there a plan to address this (and issue #123) in this provider? I've got a roughly backwards-compatible workaround in a private version of the provider that let's me optionally specify an IP as part of the network, along the lines of:
networks = [
"${data.triton_network.test_network1.id}?ip=10.1.2.3",
data.triton_network.test_network2.id
]
It's definitely a hack - the other suggestion of changing the networks attribute to a list of structures would be better in the long-run, but I didn't want to potentially deviate too far from the current behaviour of the provider.
As part of my workaround, I've upgraded the triton-go library and switched over to using NetworkObject in the API calls. Happy to contribute back my changes as part of getting this upstreamed, if it helps. Cheers :)
I think a proper fix for this should incorporate #123 and use a network_object (or as some other providers do a network_interface) block inside the machine config (and bring in the newer triton-go library with the Network Object support). An example would be:
resource "triton_machine" "name" {
# ....
network_object {
ipv4_uuid = "network UUID"
ipv4_ips = ["172.21.1.42"]
}
network_object {
ipv4_uuid = "network UUID"
}
}
Yeah, I agree - what I have is just a bit of a quick hack I'm using to unblock me at the moment - I was just wondering if anyone had made any progress in this direction.
I might have a bash at adapting my hack to the network_object structure if there is consensus behind this - would people find that useful?
Meant to add - the only concern I have with using a separate network_object structure is nic ordering issues. I've found that net0, net1, etc. are provisioned in the order of the entries in the networks array.
If network objects are specified using the set type, boot scripts on multi-homed hosts would have to enumerate the nics through the metadata client and match the network UUIDs to be sure of the order - is there a simpler way of doing this that I'm missing?
Also - what do people think about using both networks and network_object specifiers in the same triton_machine resource. Should this be prevented, or should entries in the networks array be mapped to equivalent network_objects?
For the nic ordering, I believe nics will be created in the order they are defined in the terraform config. You can specify the network (or fabric network) uuid using a data lookup, for example:
# Declare the external network
data "triton_network" "public" {
name = "Joyent-SDC-Public"
}
data "triton_fabric_vlan" "myvlan" {
name = "Private-VLAN-Production"
}
resource "triton_machine" "name" {
# ....
network_object {
ipv4_uuid = "${data.triton_network.public.id}"
}
network_object {
ipv4_uuid = "${data.triton_fabric_vlan.myvlan.id}"
ipv4_ips = ["172.21.1.42"]
}
}
I think the mixing of network_object and networks should be an error (only allow one or the other). Note that I think triton-go allows both (with NetworkObjects preceding networks).