【问题标题】:loop across modules in terraform遍历 terraform 中的模块
【发布时间】:2021-11-10 08:23:07
【问题描述】:

我需要在 GCP 中构建大约 30 个 pub sub topic,为一个 pub sub topic 创建每个模块是一个繁琐的过程,有没有更好的处理方法?

module "a" {
  source       = ""
  project_id   = var.project_id
  topic        = var.a["topic_name"]
  topic_labels = var.a["topic_labels"]
  pull_subscriptions = [
    {
      name                    = var.a["pull_subscription_name"]
      ack_deadline_seconds    = var.a["ack_deadline_seconds"]
      max_delivery_attempts   = var.a["max_delivery_attempts"]
      maximum_backoff         = var.maximum_backoff
      minimum_backoff         = var.minimum_backoff
      expiration_policy       = var.expiration_policy
      enable_message_ordering = true
    }
  ]
}

module "b" {
  source       = ""
  project_id   = var.project_id
  topic        = var.b["topic_name"]
  topic_labels = var.b["topic_labels"]
  pull_subscriptions = [
    {
      name                    = var.b["pull_subscription_name"]
      ack_deadline_seconds    = var.b["ack_deadline_seconds"]
      max_delivery_attempts   = var.b["max_delivery_attempts"]
      maximum_backoff         = var.maximum_backoff
      minimum_backoff         = var.minimum_backoff
      expiration_policy       = var.expiration_policy
      enable_message_ordering = true
    }
  ]
}

在 tfvars 中将值传递给上述模块,如下所示:

a = {
  topic_name             = "abc"
  topic_labels           = { env : "prod", purpose : "a" }
  pull_subscription_name = "abc-sub"
  ack_deadline_seconds   = 600
  max_delivery_attempts  = 3
}

b = {
  topic_name             = "bcd"
  topic_labels           = { env : "prod", purpose : "b" }
  pull_subscription_name = "bcd-sub"
  ack_deadline_seconds   = 600
  max_delivery_attempts  = 3
}

我们能否以某种方式组合 tfvars 中的变量并传递给单个模块?

我还想知道维护上述 terraform 脚本以单独保存它们或利用一个模块创建 50 个主题的最佳实践?

谢谢!

【问题讨论】:

    标签: terraform terraform-provider-gcp


    【解决方案1】:

    使用两个单独的变量,您的选择会受到一些限制,因为 Terraform 无法将这两个单独的变量视为以系统方式连接。 (与 Terraform 中的其他对象一样,每个变量都完全独立于解决依赖关系的观点。)

    但是,如果您可以将其重组为地图类型的单个变量,那么您可以使用resource for_each 系统地为地图的每个元素声明一个实例:

    variable "topics" {
      type = map(object({
        labels                 = map(string)
        pull_subscription_name = string
        ack_deadline_seconds   = number
        max_delivery_attempts  = number
      }))
    }
    
    module "topic" {
      source   = "..."
      for_each = var.topics
    
      project_id   = var.project_id
      topic        = each.key
      topic_labels = each.value.labels
      pull_subscriptions = [
        {
          name                    = each.value.pull_scription_name
          ack_deadline_seconds    = each.value.ack_deadline_seconds
          max_delivery_attempts   = each.value.max_delivery_attempts
          maximum_backoff         = var.maximum_backoff
          minimum_backoff         = var.minimum_backoff
          expiration_policy       = var.expiration_policy
          enable_message_ordering = true
        }
      ]
    }
    

    对于此示例,我假设您的 topic_name 属性将是实例的合适唯一键,因此我将其从声明的对象类型中删除,目的是将其放入映射键中。换句话说,这个topics 变量的值应该是这样的:

    topics = {
      abc = {
        labels                 = { env = "prod", purpose = "a" }
        pull_subscription_name = "abc-sub"
        ack_deadline_seconds   = 600
        max_delivery_attempts  = 3
      }
      bcd = {
        labels                 = { env = "prod", purpose = "b" }
        pull_subscription_name = "bcd-sub"
        ack_deadline_seconds   = 600
        max_delivery_attempts  = 3
      }
    }
    

    由此,Terraform 将了解到您打算使用以下地址声明模块实例:

    • module.topic["abc"]
    • module.topic["bcd"]

    因为主题名称是地址的一部分,Terraform 可以识别编辑现有主题对象(不更改其名称)和从地图中添加/删除主题之间的区别,并将其转换为声明资源实例的相应计划在模块内部。

    如果重要的是您能够更改远程系统知道的主题名称​​而不 Terraform 理解作为单独的删除和创建操作,您可以将 name 恢复为该对象的属性键入然后设置topic = each.value.name,然后地图键将用于在 Terraform 中进行跟踪,而在远程系统中根本不可见。

    【讨论】:

      【解决方案2】:

      您可以为模块使用for_each 元参数:

      https://www.terraform.io/docs/language/meta-arguments/for_each.html

      您的变量可以是for_each 可以通过的一组映射。

      话虽如此,这可能会变得过于复杂,而 IaC 的一个重要方面是保持其简单明了,在某种程度上,自我记录(这不是省略记录工作的正当理由)。

      【讨论】:

        猜你喜欢
        • 2022-12-11
        • 1970-01-01
        • 2019-03-21
        • 2021-10-05
        • 2017-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-16
        相关资源
        最近更新 更多