создание брандмауэра провайдера Cloudflare Terraform с помощью цикла
Я пытаюсь обойти ограничение, при котором создание брандмауэра разделено на 2 раздела: создание фильтра и создание правила на основе фильтра. Создание фильтра предоставляет идентификатор фильтра, который следует использовать при создании правила fw. Я не могу понять, как правильно перебирать карту, которая имеет значения для фильтра и правила и включает недавно созданный фильтр. если я просто использую простую карту с именем и выражением, все работает, но если я добавляю правила приоритета, все ломается, вот моя карта
variable "fw_allowfilters1" {
description = "list of expressions for firewall to be included in the allow rules"
type = map(object({
fvalue = string
priority = number
}))
default = {
"office_filter1" = [
{
fvalue = "ip.geoip.asnum eq 111111"
priority = 1
}
]
"office_filter2" = [
{
fvalue = "ip.src eq 8.8.8.8"
priority = 3
}
]
}
}
теперь вот мой код для фильтра и FW
resource "cloudflare_filter" "allow-filters1" {
for_each = var.fw_allowfilters1
zone_id = var.zoneid
expression = each.value.fvalue
description = each.key
//description = [for o in var.fw_allowfilters1: "Filter_${var.fw_allowfilters1.name}"]
//expression = [for o in var.fw_allowfilters1: var.fw_allowfilters1.value]
}
resource "cloudflare_firewall_rule" "whitelist-rule" {
for_each = cloudflare_filter.allow-filters1
action = "allow"
filter_id = tostring(each.value.id)
zone_id = var.zoneid
description = [for p in var.fw_allowfilters1.name: p.name ]
priority = [for p in var.fw_allowfilters1.priority: p.priority ]
}
теперь, если я не включаю приоритет, я могу выполнить for_each для вывода фильтра при создании брандмауэра, используя вывод идентификатора из ресурса и ключ для описания (поставщик cf tf использует описание в качестве имени), однако, если мне нужно добавить ключ, Мне нужно выполнить итерацию по карте со значениями плюс идентификатор, который выводится при создании фильтра, и я не уверен, как правильно его сопоставить. код в настоящее время не работает.
1 ответ
Так что я понял это, и это было непросто:) использование местных жителей помогло мне создать правильные итераторы:
resource "cloudflare_filter" "filters1" {
for_each = var.fw_rules
zone_id = var.zoneid
description = "Filter_${tostring(each.key)}"
expression = tostring(each.value[0])
}
locals {
filterids = [for f in cloudflare_filter.filters1 : f.id] //putting filter
IDs into a separate list for concat later
fwvalues = (values(var.fw_rules)) // putting values from the map of fwvalues into
a separate list to use the index position of a particular value as an interator when
creating commong object that has both filterid and fwvalues
fwkeys = (keys(var.fw_rules)) //putting keys into a separate list
//iterating over all elements in the allowfilters1, combining existing lists in the
variable with the ID value and readding the key as an element in the list
withid3 = {for p in var.fw_rules : local.fwkeys[index(local.fwvalues, p.*)] =>
concat(p, list(local.filterids[index(local.fwvalues,
p.*)]),list(local.fwkeys[index(local.fwvalues, p.*)]))} //working version
}
resource "cloudflare_firewall_rule" "fw-rules" {
for_each = local.withid3
action = each.value[2]
filter_id = each.value[4]
paused = each.value[3]
zone_id = var.zoneid
description = "FW-${tostring(each.value[2])}-${tostring(each.key)}"
priority = each.value[1]
}
где varilable - это: // синтаксис следующий: имя правила (постарайтесь быть точным = [выражение, приоритет, действие, отключено - логическое] - все значения должны быть строками, убедитесь, что кавычки правильно завершили допустимые значения для действия: блок, вызов, js_challenge, разрешить, журнал, список обхода должен поддерживаться в соответствии с приоритетом правила
variable "fw_rules" {
description = "list of expressions for firewall to be included in therules"
type = map
default = {
office_allow = ["putexpressionhere","1","allow","false"],
office_allow1 = ["putexpressionhere1","2","deny","false"]
}