Reputation: 1128
In Terraform, how can access the values from the variable below?
variable "egress_rules" {
type = list(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
default = [
{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
]
}
I tried:
resource "aws_security_group_rule" "egress" {
security_group_id = aws_security_group.new.id
type = "ingress"
for_each = var.egress_rules
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
cidr_blocks = each.value.cidr_blocks
}
But got this error:
Error: Invalid for_each argument
What is the correct way to reference this variable?
Upvotes: 1
Views: 6249
Reputation: 238877
for_each will not work with a list of maps. You have to convert it to a map. This is commonly done through a for expression:
resource "aws_security_group_rule" "egress" {
security_group_id = aws_security_group.new.id
type = "ingress"
for_each = { for idx, rule in var.egress_rules: idx => rule }
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
cidr_blocks = each.value.cidr_blocks
}
Upvotes: 3
Reputation: 1415
Adding to above answer from @Marcin
If you want to use single object instead of list then you can directly access without for_each
Instead of declaring it as list of objects; use single object as shown below
variable "egress_rules" {
type = object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
})
default = ({
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}}
}
Then access in your resource like
resource "aws_security_group_rule" "egress" {
security_group_id = aws_security_group.new.id
from_port = var.egress_rules.from_port
to_port = var.egress_rules.from_port
protocol = var.egress_rules.protocol
cidr_blocks = var.egress_rules.cidr_blocks
}
Upvotes: 0
Reputation: 2123
to set multiple properties of a resource you could use a map of objects like this:
variable "egress_rules" {
type = map(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
}
Your variable definition would be:
egress_rules = {
{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
The updated resource definition would be:
resource "aws_security_group_rule" "egress" {
security_group_id = aws_security_group.new.id
type = "egress"
for_each = var.egress_rules
from_port = each.value["from_port"]
to_port = each.value["to_port"]
protocol = each.valuep["protocol"]
cidr_blocks = each.value["cidr_blocks"]
}
Upvotes: -1