Over the past few months, I’ve been updating various Terraform modules to utilize the new features in 0.12. Among these, is the ability to iterate over dynamic blocks with for_each. Utilizing this new feature has allowed me to reduce the size of my security groups, while making them more readable. To show this feature in action, I will create a new map variable with the port as a key, and a list of CIDR blocks to allow in as the value:
variable "ec2_ingress_ports_default" {
description = "Allowed Ec2 ports"
type = list
default = {
"22" = ["192.168.1.0/24", "10.1.1.0/24" ]
"443" = ["0.0.0.0/0"]
}
To populate the Ingress statements, you can define a dynamic block, and then use for_each to iterate through the map and populate each ingress stanza:
resource "aws_security_group" "ec2_default_rules" {
name = "ecs_default_sg_rules"
dynamic ingress {
for_each = var.ec2_ingress_ports_default
content {
from_port = ingress.key
to_port = ingress.key
cidr_blocks = ingress.value
protocol = "tcp"
}
}
}
The final result will be one or more Ingress statements, each defining the CIDR block source IPs that are allowed to connect to the port:
+ {
+ cidr_blocks = [
+ "192.168.1.0/24",
+ "10.1.1.0/24",
]
+ description = ""
+ from_port = 22
+ ipv6_cidr_blocks = []
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_groups = []
+ self = false
+ to_port = 22
},
I’ve been able to drastically reduce the amount of HCL in my custom modules, which is always a good thing. There are tons of uses for this, and I will continue to refine things as I clean up old Terraform .tf files.