[英]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_one
或security_group_ids_two
已知为空列表,则concat
将完全忽略它。 如果它们被启用,那么您可以将它们安排为一个已知列表,其中一个元素的值未知,因此length(var.inbound_security_group_ids)
在所有情况下仍然具有已知值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.