Применить 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"
  }
}
Другие вопросы по тегам