'Terraform error: String required even after variable was declared as string
yesterday I asked a question to which I received a solution and updated everything which kind of seemed to remove the error. Now I have a new error. Here are the relevant files and codes:
keys>testkeys>cert1.cer, cert2.cer
keys.tfvars:
path_to_keys = [
"./keys/testkeys/cert1.cer",
"./keys/testkeys/cert2.cer",
]
variables.tf:
variable "path_to_keys" {
type = map(string)
description = "Keys are here"
}
main.tf:
vpn_client_configuration {
vpn_client_protocols = ["IkeV2","SSTP"]
address_space = [var.vpn_client_address_space]
root_certificate {
name = "Root-Cert"
public_cert_data = [var.path_to_keys]
}
}
}
When I run terraform plan
, I get this error:
Error: Incorrect attribute value type
on main.tf line 69, in resource "azurerm_virtual_network_gateway" "gw":
69: public_cert_data = [var.path_to_keys]
Inappropriate value for attribute "public_cert_data": string required.
To explain what I'm trying to do:
When I eventually run terraform apply
, I want it to include both cert1.cer
and cert2.cer
and any other certificates that I may add in the future. Please keep in mind that I am new to this so kindly go easy on me if I'm being stupid, thanks :)
Solution 1:[1]
I think there are a couple issues here. First of all, when you look at the public_cert_data
field, it is expecting a string, as per the resource definition.. Because you're giving it a list ([var.path_to_keys]
), it is throwing an error. In addition, it looks like you're getting confused at the variable typing in your definition and usage of path_to_keys
. When declaring a variable like this:
variable "path_to_keys" {
type = map(string)
description = "Keys are here"
}
You're saying that any value of path_to_keys
must be of type map(string)
. A map variable type in Terraform is a key -> value
mapping, similar to a dict in python, or a map in Java. In the case of the actual instantiation of the variable path_to_keys
you've declared:
path_to_keys = [
"./keys/testkeys/cert1.cer",
"./keys/testkeys/cert2.cer",
]
You've declared a variable of type list (or set, but that's another story). A variable of type "map" would have a key -> value mapping. For example, a valid map(string)
(what your variable definition is asking for) would be something like:
path_to_keys = {
key1 = "./keys/testkeys/cert1.cer",
key2 = "./keys/testkeys/cert2.cer",
}
It is likely that you'll either want to understand more about the data types that Terraform allows for and then figure out the appropriate type for your use case. If you don't need a key->value
relationship, and all you need is the values, using a list or set is appropriate. If you need a key->value
relationship, then a map would be appropriate.
EDIT:
If you look at the vpn_client_configuration block in the resource you're trying to create and specifically the public_cert_data
value, it shows that the data type that you're actually trying to use is string
. This is reinforced by the error message you're recieving. If you take a look at the examples there, you'll see that a valid example of the azurerm_virtual_network_gateway
resource looks like this:
resource "azurerm_virtual_network_gateway" "example" {
name = "test"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
type = "Vpn"
vpn_type = "RouteBased"
active_active = false
enable_bgp = false
sku = "Basic"
ip_configuration {
name = "vnetGatewayConfig"
public_ip_address_id = azurerm_public_ip.example.id
private_ip_address_allocation = "Dynamic"
subnet_id = azurerm_subnet.example.id
}
vpn_client_configuration {
address_space = ["10.2.0.0/24"]
root_certificate {
name = "DigiCert-Federated-ID-Root-CA"
public_cert_data = <<EOF
MIIDuzCCAqOgAwIBAgIQCHTZWCM+IlfFIRXIvyKSrjANBgkqhkiG9w0BAQsFADBn
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSYwJAYDVQQDEx1EaWdpQ2VydCBGZWRlcmF0ZWQgSUQg
Um9vdCBDQTAeFw0xMzAxMTUxMjAwMDBaFw0zMzAxMTUxMjAwMDBaMGcxCzAJBgNV
BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
Y2VydC5jb20xJjAkBgNVBAMTHURpZ2lDZXJ0IEZlZGVyYXRlZCBJRCBSb290IENB
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvAEB4pcCqnNNOWE6Ur5j
QPUH+1y1F9KdHTRSza6k5iDlXq1kGS1qAkuKtw9JsiNRrjltmFnzMZRBbX8Tlfl8
zAhBmb6dDduDGED01kBsTkgywYPxXVTKec0WxYEEF0oMn4wSYNl0lt2eJAKHXjNf
GTwiibdP8CUR2ghSM2sUTI8Nt1Omfc4SMHhGhYD64uJMbX98THQ/4LMGuYegou+d
GTiahfHtjn7AboSEknwAMJHCh5RlYZZ6B1O4QbKJ+34Q0eKgnI3X6Vc9u0zf6DH8
Dk+4zQDYRRTqTnVO3VT8jzqDlCRuNtq6YvryOWN74/dq8LQhUnXHvFyrsdMaE1X2
DwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNV
HQ4EFgQUGRdkFnbGt1EWjKwbUne+5OaZvRYwHwYDVR0jBBgwFoAUGRdkFnbGt1EW
jKwbUne+5OaZvRYwDQYJKoZIhvcNAQELBQADggEBAHcqsHkrjpESqfuVTRiptJfP
9JbdtWqRTmOf6uJi2c8YVqI6XlKXsD8C1dUUaaHKLUJzvKiazibVuBwMIT84AyqR
QELn3e0BtgEymEygMU569b01ZPxoFSnNXc7qDZBDef8WfqAV/sxkTi8L9BkmFYfL
uGLOhRJOFprPdoDIUBB+tmCl3oDcBy3vnUeOEioz8zAkprcb3GHwHAK+vHmmfgcn
WsfMLH4JCLa/tRYL+Rw/N3ybCkDp00s0WUZ+AoDywSl0Q/ZEnNY0MsFiw6LyIdbq
M/s/1JRtO3bDSzD9TazRVzn2oBqzSa8VgIo5C1nOnoAKJTlsClJKvIhnRlaLQqk=
EOF
}
revoked_certificate {
name = "Verizon-Global-Root-CA"
thumbprint = "912198EEF23DCAC40939312FEE97DD560BAE49B1"
}
}
}
So where you are attempting to give it a list of various filepaths, it is instead asking you for a string with the actual file contents. If indeed you'd like to keep it as a filepath, I'd suggest looking into the file function in order to read files from filepaths into text, and passing the output into the public_cert_data
field.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |