AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 1175834
Accepted
larsks
larsks
Asked: 2025-03-20 03:36:05 +0800 CST2025-03-20 03:36:05 +0800 CST 2025-03-20 03:36:05 +0800 CST

Terraform 中条件块内的条件块

  • 772

我正在使用 Terraform 来管理 Github 组织。我们有一个标准的“通用存储库”模块,用于确保我们的存储库共享通用配置。我想添加对配置 GitHub 页面的支持,这需要对pages元素的支持,如下所示:

  pages {
    build_type = "legacy"
    cname = "example.com"
    source {
      branch = "master"
      path   = "/docs"
    }
  }

一切都是可选的。特别是,source只有在 时才是必需的build_type == "legacy" || build_type == null,整个pages块可以省略。我不知道如何进行source条件化,所以我最终将其拆分成两个dynamic块,如下所示:

  # There are two `dynamic "pages"` blocks here to account for the fact that `source` is only required
  # if `build_type` is "legacy". The `for_each` at the top of each block will only enable the block when
  # the necessary conditions are met.
  dynamic "pages" {

    # enable this block if `pages` is not null and `build_type` is "legacy" (or null)
    for_each = var.pages == null ? [] : var.pages.build_type == "legacy" || var.pages.build_type == null ? ["enabled"] : []

    content {
      source {
        branch = var.pages.source.branch
        path   = var.pages.source.path
      }

      cname      = var.pages.cname
      build_type = var.pages.build_type
    }
  }

  dynamic "pages" {

    # enable this block if `pages` is not null and `build_type` is "workflow"
    for_each = var.pages == null ? [] : var.pages.build_type == "workflow" ? ["enabled"] : []

    content {
      cname      = var.pages.cname
      build_type = var.pages.build_type
    }
  }

pages我在模块中定义变量如下:

variable "pages" {
  description = "Configuration for github pages"
  type = object({
    source = optional(object({
      branch = string
      path   = string
    }))
    build_type = optional(string, "legacy")
    cname      = optional(string)
  })
  default = null
}

有没有更好的方法来解决这个问题?

terraform
  • 1 1 个回答
  • 20 Views

1 个回答

  • Voted
  1. Best Answer
    Martin Atkins
    2025-03-22T05:40:37+08:002025-03-22T05:40:37+08:00

    您的输入变量声明已经确保了build_type本身不能为空,因为如果为空,Terraform 将使用默认值"legacy"。我还建议添加一个验证规则来强制执行,该规则source只能在 为build_type时设置"legacy",如下所示:

    variable "pages" {
      description = "Configuration for github pages"
      type = object({
        source = optional(object({
          branch = string
          path   = string
        }))
        build_type = optional(string, "legacy")
        cname      = optional(string)
      })
      default = null
    
      validation {
        condition     = var.pages.build_type == "legacy" || var.pages.source == null
        error_message = "The source attribute may be set only when build_type is \"legacy\"."
      }
    }
    

    有了这个,您可以放心地假设模块中的其他地方var.pages.source总是会是,null除非var.pages.build_type是"legacy",并且var.pages.build_type永远不会是null。

    我认为此时其余的问题可以简化为:pages仅当var.pages不为空时才声明块,并且仅当不为空时才声明source块内的块,可以这样写:pagesvar.pages.source

      dynamic "pages" {
        for_each = var.pages[*]
        content {
          cname      = pages.value.cname
          build_type = pages.value.build_type
    
          dynamic "source" {
            for_each = pages.value.source[*]
            content {
              branch = source.value.branch
              path   = source.value.path
            }
          }
        }
      }
    

    将[*]运算符应用于不属于列表、元组或集合类型的值会导致 Terraform 返回一个包含零个或一个元素的元组,具体取决于操作数是否为null。此处理记录在单值为列表中。

    例如,如果var.pages为空,则上面的最外层块实际上具有for_each = [],而如果var.pages为非空,则为for_each包含相同对象的单元素列表var.pages,因此这实际上声明了零个或一个pages块。嵌套块也是如此dynamic "source"。


    附加奖励:[*]将单个值转换为零或一个元素的元组的行为在函数形式上one具有逆。

    尽管在这种情况下这没有直接用处,但如果模块中的其他内容稍后需要引用先前使用 转换为元组的内容,则这两个功能通常会一起出现在模块中[*],如与“Splat”运算符的关系中所示。

    因此,我认为值得学习它们,因为它们允许您在可能为空的单个值和零个或一个元素的序列之间自由地来回移动,就像您使用其他 Terraform 语言功能一样,这些功能期望与您当前持有的任何功能相反。

    零或一元素序列本质上具有与可能为空的单个值相同的表达能力,但许多 Terraform 语言功能优先使用序列,因为它们可以推广到支持任意数量的元素。

    • 1

相关问题

  • 子网没有在 azure 上使用 terraform 创建,如何解决?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve