Reputation: 549
I'm learning terraform by building a template to create my infrastructure in the hetzner cloud. For this purpose I'm using the hcloud provider.
I create a map variable hosts to create >1 server with different configuration.
variable "hosts" {
type = map(object({
name = string
serverType = string
serverImage = string
serverLocation = string
serverKeepDisk = bool
serverBackup = bool
ip = string
}))
}
This is working fine. But I need to configure also volumes. I need only for 2 servers additional volumes and terraform has to check if variable volume is true or not. If true a new volume with given details should be created and attached to the server. For this I edit my variable hosts:
variable "hosts" {
type = map(object({
name = string
serverType = string
serverImage = string
serverLocation = string
serverKeepDisk = bool
serverBackup = bool
ip = string
volume = bool
volumeName = string
volumeSize = number
volumeFormat = string
volumeAutomount = bool
volumeDeleteProtection = bool
}))
}
in the main.tf the volume block looks like this, but it doesnt work because for_each and count cant be used together. How can I get what I'm looking for? Is that possible?
resource "hcloud_volume" "default" {
for_each = var.hosts
count = each.value.volume ? 1 : 0
name = each.value.volumeName
size = each.value.volumeSize
server_id = hcloud_server.default[each.key].id
automount = each.value.volumeAutomount
format = each.value.volumeFormat
delete_protection = each.value.volumeDeleteProtection
}
Upvotes: 6
Views: 22835
Reputation: 28739
The former iterative meta-argument count
will not provide you with the functionality you need here, as you need to access the volume
bool type on a per var.hosts
iteration in the map. To that end, you can add a conditional in a for
expression within the for_each
meta-argument.
for_each = { for host, values in var.hosts: host => values if values.volume }
This will construct a map for the value of the for_each
meta-argument. It will contain every key value pair of var.hosts
for which the volume
object key is true
.
It would seem like this would be a good fit for a collect
or map
method or function which transforms list
and map
types and exist in many other languages, but these do not yet exist in Terraform. Therefore, we use a for
expression lambda equivalent.
Upvotes: 8