[英]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.