繁体   English   中英

Terraform 解耦安全组依赖

[英]Terraform decouple Security Group dependency

这是用Terraform v0.12.9测试的

我通常将安全组和安全组规则作为单独的资源进行管理,如下例所示:

resource "aws_security_group" "this" {
  count       = var.create ? 1 : 0
  name_prefix = "${var.security_group_name}_"
  vpc_id      = var.vpc_id

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_security_group_rule" "ingress_rules" {
  count                     = var.create ? length(var.inbound_security_group_ids) : 0

  security_group_id         = aws_security_group.this[0].id
  type                      = "ingress"

  from_port                 = var.from_port
  to_port                   = var.to_port
  protocol                  = "tcp"
  source_security_group_id  = var.inbound_security_group_ids[count.index]
}

其实现如下所示:

module "test_module" {
  source                     = "../path/to/module/"

  create                     = true
  vpc_id                     = "vpc-xxxxxx"
  security_group_name        = "${var.service_name}-db"
  from_port                  = 1234
  to_port                    = 1234
  inbound_security_group_ids = [
    module.service.security_group_id_one,
    module.service.security_group_id_two
  ]
}

问题

如果没有创建module.service的输出,我希望它能够工作。 在那种情况下,我的期望是length(var.inbound_security_group_ids)应该评估为0导致未创建安全组规则

实际发生的是length(var.inbound_security_group_ids)在未创建module.service时计算为2 这大概是因为它是一个由两个空白字符串组成的数组["", ""]

根据Terraform 文档,我可以使用compact的 function 来处理这个问题,它会从数组中删除空字符串。

resource "aws_security_group_rule" "ingress_rules" {
  count                     = var.create ? length(compact(var.inbound_security_group_ids)) : 0

  security_group_id         = aws_security_group.this[0].id
  type                      = "ingress"

  from_port                 = var.from_port
  to_port                   = var.to_port
  protocol                  = "tcp"
  source_security_group_id  = var.inbound_security_group_ids[count.index]
}

然而,这个问题是 Terraform 无法确定plan ,因为它不知道var.inbound_security_group_ids直到apply-time评估什么。 这是错误消息(用于上下文):

“count”值取决于资源属性,在应用之前无法确定,因此 Terraform 无法预测将创建多少个实例。 要解决此问题,请使用 -target 参数首先仅应用计数所依赖的资源。

问题

是否可以像这样解耦安全组,以便即使在source_security_group_id属性没有值时仍会创建它?

使用 Terraform 中可能为空的列表或集合通常比使用可能未设置的单个值更容易,原因与您观察到的有关:它将值是否设置与实际值分开是,因此即使值本身不知道,也可以知道该值的存在

在这种情况下,您可以通过更改从service模块返回安全组 ID 的方式来解决此问题,以便这些输出中的每一个都是安全组 ID列表,而不是可能是有效安全组 ID 或一个空字符串:

module "test_module" {
  source                     = "../path/to/module/"

  create                     = true
  vpc_id                     = "vpc-xxxxxx"
  security_group_name        = "${var.service_name}-db"
  from_port                  = 1234
  to_port                    = 1234
  inbound_security_group_ids = concat(
    module.service.security_group_ids_one,
    module.service.security_group_ids_two,
  )
}

如果security_group_ids_onesecurity_group_ids_two已知为空列表,则concat将完全忽略它。 如果它们启用,那么您可以将它们安排为一个已知列表,其中一个元素的值未知,因此length(var.inbound_security_group_ids)在所有情况下仍然具有已知值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM