地形解耦安全组依赖性

问题描述 投票:0回答:1

已通过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)时,2的值为module.service。据推测这是因为它是两个空白字符串的数组["", ""]

根据Terraform documentation,我可以使用compact函数处理此问题,该函数将从数组中删除空字符串。

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属性没有值也仍然可以创建该安全组?

amazon-web-services terraform aws-security-group
1个回答
2
投票
出于与您所观察到的原因相关的原因,使用Terraform中可能为空的列表或集通常要比使用可能未设置的单个值要容易得多:它将值是否与值实际上是,因此即使值本身未知,也可以知道该值的

presence。

在这种情况下,您可以通过更改从service模块返回安全组ID的方式来解决该问题,以使每个输出都是安全组ID的

list

,而不是一个可能是有效的安全组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将完全忽略它。如果启用了[[are
,则可以将它们安排为一个已知列表,其中一个元素的值未知,因此length(var.inbound_security_group_ids)在所有情况下仍将具有已知值。
© www.soinside.com 2019 - 2024. All rights reserved.