resource "aws_security_group" "sg" { count = length(var.security-groups) name = var.security-groups[count.index].name description = var.security-groups[count.index].description vpc_id = var.vpc-id tags = { Name = var.security-groups[count.index].name } } // see https://www.terraform.io/docs/configuration/functions/flatten.html locals { rules = flatten([ for sg_key, sg in var.security-groups : [ for rule_key, rule in sg.rules : { sg_key = trimspace(sg.name) rule_key = rule[0] sg_name = sg.name protocol = rule[1] cidr_blocks = rule[2] from_port = rule[3] to_port = rule[4] type = rule[5] description = rule[6] } ] ]) } resource "aws_security_group_rule" "rules" { for_each = { for rule in local.rules : "${rule.sg_key}.${rule.rule_key}" => rule } security_group_id = matchkeys(aws_security_group.sg.*.id, aws_security_group.sg.*.name, [each.value.sg_name])[0] protocol = each.value.protocol source_security_group_id = substr(each.value.cidr_blocks,0,2) == "sg" ? each.value.cidr_blocks : null cidr_blocks = substr(each.value.cidr_blocks,0,2) != "sg" ? [each.value.cidr_blocks] : null from_port = each.value.from_port to_port = each.value.to_port type = each.value.type description = "${each.value.description} (${each.value.sg_name}.${each.value.rule_key})" }