Применить cloudflare_zone_settings_override к нескольким зонам
Я просто мокну от Terraform, но не вижу очевидного способа удержать меня от повторения.
У меня есть несколько зон в Cloudlfare, которыми я хочу управлять. Эти зоны будут иметь очень похожие настройки, и я хочу, чтобы .tf
файлы должны быть как короткими, так и читаемыми.
Допустим, у меня есть example1.com example2.com example3.com... Я добавляю их с помощью следующего кода:
resource "cloudflare_zone" "example1"{
zone = "example1.com"
}
resource "cloudflare_zone" "example2"{
zone = "example2.com"
}
resource "cloudflare_zone" "example3"{
zone = "example3.com"
}
Все идет нормально.
Теперь я хочу применить идентичные настройки ко всем моим зонам, используя cloudflare_zone_settings_override
поставщик.
Глядя на документацию, это прямо для одной зоны. Но я бы предпочел не делать это для каждой зоны:
resource "cloudflare_zone_settings_override" "example1" {
name = "$example1.com"
settings {
brotli = "on"
security_level = "high"
opportunistic_encryption = "on"
automatic_https_rewrites = "on"
mirage = "on"
waf = "on"
minify {
css = "on"
js = "off"
html = "off"
}
}
}
Каков наилучший способ применить их ко всем (или некоторым) из зон Cloudflare?
Спасибо
3 ответа
У Terraform есть несколько способов минимизировать повторение.
Вы можете просмотреть список, используя count
метапараметр, создающий ресурсы по мере необходимости:
variable "zones" {
type = "list"
}
resource "cloudflare_zone" "zones" {
count = "${length(var.zones)}"
zone = "${var.zones[count.index]}"
}
resource "cloudflare_zone_settings_override" "settings" {
count = "${length(var.zones)}"
name = "${cloudflare_zone.zones.*.zone[count.index]}"
settings {
brotli = "on"
security_level = "high"
opportunistic_encryption = "on"
automatic_https_rewrites = "on"
mirage = "on"
waf = "on"
minify {
css = "on"
js = "off"
html = "off"
}
}
}
Обратите внимание на использование "${cloudflare_zone.zones.*.zone[count.index]}"
в настройках зоны для названия зоны. Это гарантирует, что Terraform знает, что ему нужно создать зону Cloudflare перед созданием переопределения параметров зоны, а не видеть зависимость между ними и пытаться создать их одновременно, что может потенциально привести к сбою, поскольку зона еще не создана. создается, когда Terraform пытается создать переопределение настроек зоны.
Или вы можете перенести конфигурацию зоны в модуль, что позволит вам абстрагироваться, предоставляя более ограниченный контроль над ресурсом вызывающей стороне модуля:
Модули / CloudFlare-зона / main.tf
variable "zone" {}
variable "waf" {
default = "on"
}
resource "cloudflare_zone" "zone" {
zone = "${var.zone}"
}
resource "cloudflare_zone_settings_override" "settings" {
name = "${cloudflare_zone.zone.zone}"
settings {
brotli = "on"
security_level = "high"
opportunistic_encryption = "on"
automatic_https_rewrites = "on"
mirage = "on"
waf = "${var.waf}"
minify {
css = "on"
js = "off"
html = "off"
}
}
}
Этот модуль имеет обязательную переменную zone
и необязательная переменная по умолчанию waf
это определяет, следует ли включить WAF для зоны. Все остальные параметры установлены для вызывающей стороны, поэтому модуль можно просто вызвать несколько раз, например так:
module "cloudflare_zone_example1" {
source = "path/to/module"
zone = "example1.com"
}
module "cloudflare_zone_example2" {
source = "path/to/module"
zone = "example2.com"
waf = "off"
}
Чтобы избежать повторения кода Terraform, вы можете:
- создать модуль и использовать его три раза
- установите свойство count в три и создайте список ваших доменных имен
Пример для второго решения:
local {
domain_names = [
example1.com,
example2.com,
example3.com
]
}
resource "cloudflare_zone" "these_zones" {
count = "${length(local.domain_names)}"
zone = "${element(local.domain_names, count.index)}"
}
resource "cloudflare_zone_settings_override" "these_zones_settings" {
count = "${length(local.domain_names)}"
name = "${element(local.domain_names, count.index)}"
settings {
brotli = "on"
security_level = "high"
opportunistic_encryption = "on"
automatic_https_rewrites = "on"
mirage = "on"
waf = "on"
minify {
css = "on"
js = "off"
html = "off"
}
}
}
PS: этот код написан для terraform < 0.12
Альтернативное решение с использованием этого модуля . Вот готовый к использованию пример:
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = ">= 3.12.1"
}
}
}
variable "cloudflare_api_token" {
type = string
sensitive = true
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
locals {
# All your zones go here
zones = ["acme.com", "example.com"]
}
module "zones" {
source = "registry.terraform.io/alex-feel/zone/cloudflare"
version = "1.7.0"
for_each = toset(local.zones)
zone = each.value
brotli = "on"
security_level = "high"
opportunistic_encryption = "on"
automatic_https_rewrites = "on"
mirage = "on"
waf = "on"
minify = {
css = "on"
}
}