specifically using the vsphere provider as documented here:
was wondering how to implement multiple network stanzas when involving a datasource:
ref: https://www.terraform.io/docs/providers/vsphere/r/virtual_machine.html
specifically:
...
data "vsphere_network" "network" {
name = "var.networks.label"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
...
resource "vsphere_virtual_machine" "vm" {
...
network_interface {
network_id = "${data.vsphere_network.network.id}"
}
}
...
I’d like to do replace network_interface with something like
dynamic "network_interface" {
for_each = [for s in var.networks: {
networkid = networks.label
}]
content {
networkid = network_interface.networkid
}
}
But I need to somehow get the data source to work across the array of hashes -
variable "networks" { default = [
{label = "foo"},
{label = "bar"}
]
}
I hope this is a good explanation of what I am trying to do with my psuedo code attempt.
Hi @rismoney!
What you’ve shared so far seems to be on the right track, as far as I can tell. Did you get some specific error when you tried that? If you could share it, we can hopefully suggest how to address that error.
I think I am probably missing a detail here because it’s not clear to me how the second example relates to the data source in the first example. I think seeing how Terraform behaved when you tried this would help to understand what I’m missing.
It’s not a question of an error (yet). My question is with regard to the data source.
How can I have the datasource iterate through the list map.
In typing this up, I need to have the value for
network_id = "${data.vsphere_network.network.id}"
not the networks.label
value.
If I’m understanding correctly what you want to achieve, I think the following should do it:
variable "networks" {
type = list(object({
label = string
}))
}
data "vsphere_network" "network" {
count = length(var.networks)
name = var.networks[count.index].label
datacenter_id = data.vsphere_datacenter.dc.id
}
resource "vsphere_virtual_machine" "vm" {
# ...
dynamic "network_interface" {
for_each = data.vsphere_network.network
content {
networkid = network_interface.value.id
}
}
}
The key is to use multiple instances of the data resource, with one instance per network you want to connect with, and then generate a network_interface
block for each of those instances.
2 Likes
Yes that is absolutely what I was trying to achieve. I will give it a try. I didn’t realize I can do count on data source and peg it against the size of the list
This works great, but now I’m struggling to assign IPs and Netmasks to those networks inside the clone block. Say i have these 2 variable lists:
vsphere_virtual_machine_ipv4_address = [ "172.23.32.115", "172.23.64.200",]
vsphere_virtual_machine_ipv4_mask = [ "20", "20" ]
And i want to dynamically assign it to the the N interfaces i created:
clone {
template_uuid = data.vsphere_virtual_machine.template.id
customize {
linux_options {
host_name = var.vsphere_virtual_machine_name
domain = var.vsphere_virtual_machine_domain
}
dynamic "network_interface" {
for_each = var.vsphere_virtual_machine_ipv4_address
content {
ipv4_address = var.vsphere_virtual_machine_ipv4_address
ipv4_netmask = var. vsphere_virtual_machine_ipv4_mask
}
}
ipv4_gateway = var.vsphere_virtual_machine_ipv4_gateway
dns_server_list = var.vsphere_virtual_machine_dns_list
dns_suffix_list = var.vsphere_virtual_machine_suffix_list
}
}
But i’m not able to iterate over the “vsphere_virtual_machine_ipv4_address” list. I tried using indexes and attributes but it’s not working either.
Need some help on how to get the secrets from Azure key vault using dynamic blocks. Searched around and also saw the documentation, couldnt find my help.
I have the below code to retrieve secrets. But it is repeating for each secret to be retrieved and if a key vault has a different set of secrets to retrieve then i have to define them in a separate tf file. Rather i would like to pass the secret names as vars to a tf file which would iterate the list of vars and build the data blocks using dynamic blocks. Is there an option to do this in terraform 0.12 now?
main.tf
data “azurerm_key_vault_secret” “secret1” {
name = “secret1”
key_vault_id = “/subscriptions/{var.subscription_id}/resourceGroups/{var.kvsecrets_rg_name}/providers/Microsoft.KeyVault/vaults/{var.kv_name}"
}
data "azurerm_key_vault_secret" "secret2" {
name = "secret2"
key_vault_id = "/subscriptions/{var.subscription_id}/resourceGroups/{var.kvsecrets_rg_name}/providers/Microsoft.KeyVault/vaults/{var.kv_name}”
}
output.tf
output “secret1” {
sensitive = true
value = “${data.azurerm_key_vault_secret.secret1.value}”
}
output “secret2” {
sensitive = true
value = “${data.azurerm_key_vault_secret.secret2.value}”
}
Have you managed anything since then?
There’s a network_interface
block also inside linux_options
, but that cannot be solved through a dynamic block. Which renders the whole dynamic block for network_interfaces completely useless, because defining only one interface inside the clone will error out
The number of network adapter settings in the customization specification: 1 does not match the number of network adapters present in the virtual machine: 2.