This is tested with Terraform v0.12.9
I generally manage security groups and security group rules as separate resources, as in the below example:
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]
}
The implementation for this would look something like the below:
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
]
}
Problem
I want this to work if the outputs from the module.service
aren't created. In that scenario my expectation is that length(var.inbound_security_group_ids)
should evaluate to 0
resulting in the security group rules not being created
What actually happens is that length(var.inbound_security_group_ids)
evaluates to 2
when module.service
isn't created. This is presumably because it is an array of two blank strings ["", ""]
According to the Terraform documentation I can handle this with the compact
function, which removes empty strings from an array.
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]
}
The problem with this, however, is that Terraform is unable to determine the plan
because it doesn't know what var.inbound_security_group_ids
evaluates to until apply-time
. This is the error message (for context):
The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use the -target argument to first apply only the resources that the count depends on.
Question
Is it possible to decouple a security group like this so that it will still be created even when the source_security_group_id
attribute has no values?