Reputation: 25
I'm really new to terraform and I'm having an issue doing something very basic. I will only put in the relevant codes to help save time
In my variables.tf file, I have the following:
variable "keys_location" {
type = string
description = "keys are here"
}
I have kept the keys that are referenced in my wrkspace.vars, I have the following:
keys_location = {
"./keys/testing/certificate1.cer",
"./keys/testing/certificate2.cer",
}
And in my main.tf, I have this
resource "azurerm_virtual_network_gateway" "gw" {
name = "testing-${terraform.workspace}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
type = "Vpn"
vpn_type = "RouteBased"
active_active = false
enable_bgp = false
sku = "VpnGw1"
ip_configuration {
name = "config"
public_ip_address_id = azurerm_public_ip.ip.id
private_ip_address_allocation = "Dynamic"
subnet_id = azurerm_subnet.subnet.id
}
test_config {
test_protocols = ["IkeV2","SSTP"]
address_space = [var.vpn_test_address_space]
dynamic "keys_location" {
for_each = var.keys_location
root_certificate {
name = "Root-Cert"
public_cert_data = file(var.keys_location)
}
}
}
When I do a terraform plan, the error I get is:
Error: Missing attribute value
on vars/wrkspace.vars line 5:
4: keys_location = {
5: "./keys/testing/certificate1.cer",
Expected an attribute value, introduced by an equals sign ("=").
How can this issue be fixed?
Upvotes: 0
Views: 12551
Reputation: 74694
I can see two problems with what you shared, and one of them is the cause of this error.
The error itself is reporting that you've used braces { }
, which are delimiters used for writing object/map values, but the content of the braces looks like you intended to define a list instead.
If you did intend to define a list then you should use square brackets [ ]
to indicate that:
keys_location = [
"./keys/testing/certificate1.cer",
"./keys/testing/certificate2.cer",
]
If you actually did intend to declare a map then you'll need to choose a unique key for each element, which is what this error message is trying to tell you (because it's assuming you wanted to declare a map). I can't predict what would be good map keys so I've just used some placeholder ones for example here:
keys_location = {
cert1 = "./keys/testing/certificate1.cer",
cert2 = "./keys/testing/certificate2.cer",
}
If you make a change like I suggested above then I expect you will encounter the second error, which is that you've declared your variable as type = string
but you've assigned it a list or map value. To make that work you'll need to specify a more appropriate type constraint for the variable.
If you intended to provide a list (using square brackets [ ]
) then you could declare the variable as follows:
variable "keys_location" {
type = list(string)
}
If you intended to provide a map (using braces { }
) then you could declare the variable as follows:
variable "keys_location" {
type = map(string)
}
Upvotes: 1
Reputation: 178
The Terraform for_each meta-argument operates on maps and sets, and iteration is done over either keys and values (in the case of maps) or values (in the case of sets). In order to iterate over the values in a set, one should use each.key
.
In your case, because you're actually iterating over the values in the path_to_keys
variable, the keys_location
variable is unnecessary. You should instead reference each of the values inside the path_to_keys
variable.
One possible solution would be changing your main.tf
to the following:
resource "azurerm_virtual_network_gateway" "gw" {
name = "testing-${terraform.workspace}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
type = "Vpn"
vpn_type = "RouteBased"
active_active = false
enable_bgp = false
sku = "VpnGw1"
ip_configuration {
name = "config"
public_ip_address_id = azurerm_public_ip.ip.id
private_ip_address_allocation = "Dynamic"
subnet_id = azurerm_subnet.subnet.id
}
test_config {
test_protocols = ["IkeV2","SSTP"]
address_space = [var.vpn_test_address_space]
dynamic "keys_location" {
for_each = var.path_to_keys
root_certificate {
name = "Root-Cert"
public_cert_data = file(each.key)
}
}
}
your variables.tf
to:
variable "path_to_keys" {
type = set
description = "keys are here"
}
and your wrkspace.tfvars
to:
path_to_keys = [
"./keys/testing/certificate1.cer",
"./keys/testing/certificate2.cer",
]
Upvotes: 1