首页 > 解决方案 > 将 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 中的所有(或部分)区域的最佳方式是什么?

谢谢

标签: terraformterraform-provider-cloudflare

解决方案


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-zone/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"
    }
  }
}

然后,此模块具有一个必需的变量 ofzone和一个可选的默认变量 of 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"
}

推荐阅读