在 terraform 中跨模块循环

桑杰议员

我需要在 GCP 中构建大约 30 个发布子主题,为发布子主题创建每个模块是一个乏味的过程,有没有更好的方法来处理它?

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 中的其他对象一样,完全独立于依赖解决的观点。)

但是,如果您可以将其重构为地图类型的单个变量,那么您可以使用资源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 中进行跟踪,而在远程系统中根本不可见。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章