I have a security group resource in the module called "networking":
resource "aws_security_group" "dev_sg" {
for_each = var.security_groups
name = each.value.name
description = each.value.description
vpc_id = aws_vpc.dev_vpc.id
dynamic "ingress" {
for_each = each.value.ingress
#iterator = port
content {
from_port = ingress.value.from
to_port = ingress.value.to
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Also, outside of the module, in the root module i have locals.tf file which is this:
locals {
security_groups = {
public = {
name = "public_sg"
description = "Security Group for Public Access"
ingress = {
ssh = {
from = 22
to = 22
protocol = "tcp"
cidr_blocks = [var.access_ip]
}
http = {
from = 80
to = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
}
And here is the module definition:
module "networking" {
source = "./networking"
vpc_cidr = local.vpc_cidr
security_groups = local.security_groups
public_sn_count = 2
private_sn_count = 3
}
Now, my question is, how can I reference a security group ID instead of cidr_block inside locals.tf file? I have no clue how to implement this?
For example:
cidr_blocks = ["192.168.8.0/21", "${var.security_group_id}"]
You need to use security_groups in aws_security_group ingress or egress
resource "aws_security_group" "dev_sg" {
for_each = var.security_groups
name = each.value.name
description = each.value.description
vpc_id = aws_vpc.dev_vpc.id
dynamic "ingress" {
for_each = each.value.ingress
#iterator = port
content {
from_port = ingress.value.from
to_port = ingress.value.to
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
security_groups = lookup(ingress.value, "security_groups", null)
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
locals {
security_groups = {
public = {
name = "public_sg"
description = "Security Group for Public Access"
ingress = {
ssh = {
from = 22
to = 22
protocol = "tcp"
cidr_blocks = [var.access_ip]
security_groups = [var.security_group_id]
}
http = {
from = 80
to = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"],
security_groups = [var.security_group_id]
}
}
}
}
module "networking" {
source = "./networking"
vpc_cidr = local.vpc_cidr
security_groups = local.security_groups
public_sn_count = 2
private_sn_count = 3
}
Related
I’ve created primary_sg, secondary_sg_tcpci, secondary_sg_tcpqa, secondary_sq_tcpprod security groups.
primary_sg has three outbound rules to it and each one is associated with secondary_sg securitygroup as destination.
For secondary, I created three security groups secondary_sg_tcpci, secondary_sg_tcpqa and secondary_sg_tcpprod. Each of these security group inbound rules are associated again with same primary_sg securitygroup as source in it and referring to some local variables.
main.tf
data "aws_vpc" "default" {
id = "vpc-1234"
}
data "aws_security_groups" "server_sg"{
tags = {
name = "server_sg"
}
}
locals {
vpc_id = data.aws_vpc.default.id
server_jumpbox_security_groups = data.aws_security_groups.server_sg.id
}
####### primary_sg###########
resource "aws_security_group" "primary_sg" {
name = "primary_security_group"
description = "Allows outbound rules"
vpc_id = local.vpc_id
}
resource "aws_security_group_rule" "rule_01" {
type = "egress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = aws_security_group.secondary_sg_tcpci.id ## Associating secondary_sg_tcpci as destination security group ####
description = "primary_sg rule01"
security_group_id = aws_security_group.primary_sg.id
}
resource "aws_security_group_rule" "rule_02" {
type = "egress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = aws_security_group.secondary_sg_tcpqa.id ## Associating secondary_sg_tcpqa as destination security group ####
description = "primary_sg rule02"
security_group_id = aws_security_group.primary_sg.id
}
resource "aws_security_group_rule" "rule_03" {
type = "egress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = aws_security_group.secondary_sg_tcpprod.id ## Associating secondary_sg_tcpprod as destination security group ####
description = "primary_sg rule02"
security_group_id = aws_security_group.primary_sg.id
}
########secondary_sg#########
resource "aws_security_group" "secondary_sg_tcpci" {
name = "secondary_sg_tcpci"
description = "RDS SG for TCPCI env"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [local.server_jumpbox_security_groups]
description = "Server SG"
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = ["${aws_security_group.primary_sg.id}"]
description = "Secondary SG"
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_security_group" "secondary_sg_tcpqa" {
name = "secondary_sg_tcpqa"
description = "RDS SG for TCPQA env"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [local.server_jumpbox_security_groups]
description = "Server SG"
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = ["${aws_security_group.primary_sg.id}"]
description = "Secondary SG"
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_security_group" "secondary_sg_tcpprod" {
name = "secondary_sg_tcpprod"
description = "RDS SG for TCPQA env"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [local.server_jumpbox_security_groups]
description = "Server SG"
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = ["${aws_security_group.primary_sg.id}"]
description = "Secondary SG"
}
lifecycle {
create_before_destroy = true
}
}
I tried using for_each loop.
main.tf
resource "aws_security_group" "secondary_sg_tcpci" {
for_each = var.config
name = "${each.key}-rds"
description = "RDS SG for TCPCI env"
vpc_id = data.aws_vpc.default.id
dynamic "ingress" {
for_each = var.ingress_rules
iterator = port
content {
from_port = ingress.value.port
to_port = ingress.value.port
protocol = ingress.value.protocol
security_groups = ["${aws_security_group.primary_sg.id}"]
}
}
}
resource "aws_security_group" "primary_sg" {
name = "primary_security_group"
description = "Allows outbound rules"
vpc_id = local.vpc_id
}
resource "aws_security_group_rule" "rule_01" {
type = "egress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = aws_security_group.secondary_sg_tcpci.id ## Associating secondary_sg_tcpci as destination security group ####
description = "primary_sg rule01"
security_group_id = aws_security_group.primary_sg.id
}
resource "aws_security_group_rule" "rule_02" {
type = "egress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = aws_security_group.secondary_sg_tcpqa.id ## Associating secondary_sg_tcpqa as destination security group ####
description = "primary_sg rule02"
security_group_id = aws_security_group.primary_sg.id
}
vars.tf
variable "config" {
description = "Security groups configuration"
type = map(object({
name = string
}))
default = {
"sg-1" = {
name = "sg-1"
}
"sg-2" = {
name = "sg-2"
}
}
}
variable "ingress_rules" {
type = map(object({
port = number
protocol = string
}))
default = {
"22" = {
cidr_block = ["0.0.0.0/0"]
port = 22
protocol = "tcp"
}
"22" = {
cidr_block = ["0.0.0.0/0"]
port = 22
protocol = "tcp"
}
}
}
Since you are creating the SG with for_each, you can only access the SG attributes but using proper keys. There is also a small error in other parts of code as in the dynamic block you are setting the iterator and then later on in the content you are not using it, so you can drop it (as it will default to the dynamic block name which is ingress):
resource "aws_security_group" "secondary_sg_tcpci" {
for_each = var.config
name = "${each.key}-rds"
description = "RDS SG for TCPCI env"
vpc_id = data.aws_vpc.default.id
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.port
to_port = ingress.value.port
protocol = ingress.value.protocol
security_groups = [aws_security_group.primary_sg.id]
}
}
}
resource "aws_security_group" "primary_sg" {
name = "primary_security_group"
description = "Allows outbound rules"
vpc_id = local.vpc_id
}
resource "aws_security_group_rule" "rule_01" {
for_each = aws_security_group.secondary_sg_tcpci
type = "egress"
from_port = 22
to_port = 22
protocol = "tcp"
source_security_group_id = each.value.id # <--- this is how you would reference the security IDs for all the SGs created with `for_each`
description = "primary_sg rule01"
security_group_id = aws_security_group.primary_sg.id
}
This is only for the one SG created with for_each. This technique is called resource chaining with for_each [1]. If you need to repeat the same for other SGs (tcpqa, tcpprod etc.) you would have to adjust the rest of the code.
[1] https://developer.hashicorp.com/terraform/language/meta-arguments/for_each#chaining-for_each-between-resources
My code will create security groups as well as ingress/egress as we give the list of security groups and rules in the dev.tfvars file
The code ran successfully but created security groups takes ingress/egress rules from all given security groups.
./security.tf
resource "aws_security_group" "sg" {
count = length(var.vpc_config.security_groups)
name = var.vpc_config.security_groups[count.index].name
description = var.vpc_config.security_groups[count.index].description
vpc_id = var.vpc_id
dynamic "ingress" {
for_each = var.vpc_config.security_groups
content {
from_port = ingress.value.ingress.from_port
to_port = ingress.value.ingress.to_port
protocol = ingress.value.ingress.protocol
cidr_blocks = ingress.value.ingress.cidr_block
}
}
dynamic "egress" {
for_each = var.vpc_config.security_groups
content {
from_port = egress.value.egress.from_port
to_port = egress.value.egress.to_port
protocol = egress.value.egress.protocol
cidr_blocks = egress.value.egress.cidr_block
}
}
tags = {
Name = var.vpc_config.security_groups[count.index].name
Environment = var.vpc_config.environment
}
}
./dev.tfvars
vpc_config = {
security_groups = [ {
name = "sg_1"
description = "security group 1"
ingress = {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_block = ["0.0.0.0/0"]
}
egress = {
from_port = 0
to_port = 0
protocol = "-1"
cidr_block = ["0.0.0.0/0"]
}
},
{
name = "sg_2"
description = "security group 2"
ingress = {
from_port = 21
to_port = 21
protocol = "tcp"
cidr_block = ["0.0.0.0/0"]
}
egress = {
from_port = 443
to_port = 443
protocol = "http"
cidr_block = ["0.0.0.0/0"]
}
}
]
}
It will create two security groups with one ingress and one egress each but it creates two security groups with two ingress and two egress each.
If your goal is to create a 2 security groups, each having a certain ingress and egress rules explicitly defined, you do not want to have dynamic blocks. With dynamic blocks, you will create an inner loop, which is not what you would want.
I recommend using only one for_each at the resource level and no dynamic blocks:
resource "aws_security_group" "sg" {
for_each = {
for sg in var.vpc_config.security_groups : sg.name => sg
}
name = each.value.name
description = each.value.description
vpc_id = var.vpc_id
ingress {
from_port = each.value.ingress.from_port
to_port = each.value.ingress.to_port
protocol = each.value.ingress.protocol
cidr_blocks = each.value.ingress.cidr_block
}
egress {
from_port = each.value.egress.from_port
to_port = each.value.egress.to_port
protocol = each.value.egress.protocol
cidr_blocks = each.value.egress.cidr_block
}
tags = {
Name = each.value.name
Environment = var.vpc_config.environment
}
}
If you want to use count, you can do it as follows:
resource "aws_security_group" "sg" {
count = length(var.vpc_config.security_groups)
name = var.vpc_config.security_groups[count.index].name
description = var.vpc_config.security_groups[count.index].description
vpc_id = var.vpc_id
ingress {
from_port = var.vpc_config.security_groups[count.index].ingress.from_port
to_port = var.vpc_config.security_groups[count.index].ingress.to_port
protocol = var.vpc_config.security_groups[count.index].ingress.protocol
cidr_blocks = var.vpc_config.security_groups[count.index].ingress.cidr_block
}
egress {
from_port = var.vpc_config.security_groups[count.index].egress.from_port
to_port = var.vpc_config.security_groups[count.index].egress.to_port
protocol = var.vpc_config.security_groups[count.index].egress.protocol
cidr_blocks = var.vpc_config.security_groups[count.index].egress.cidr_block
}
tags = {
Name = var.vpc_config.security_groups[count.index].name
Environment = var.vpc_config.environment
}
}
I'm trying to create a reusable security group and its rules using for_each. While passing the cidr_blocks = list(string), I'm getting the below error. If I remove the cidr_blocks the code works fine
╷
│ Error: Invalid index
│
│ on ../../modules/security/main.tf line 18, in resource "aws_security_group" "app_sg":
│ 18: cidr_blocks = ingress.value["cidr_blocks"]
│ ├────────────────
│ │ ingress.value is object with 3 attributes
│
│ The given key does not identify an element in this collection value.
╵
Root Module
###################################
# Create a security group & rules #
###################################
module "application_sg" {
source = "../../modules/security"
create_sg = var.create_sg
name_suffix = var.name_suffix
sg_name = var.sg_name
environment = local.common-tags.environment
vpc_id = one(module.mgt_vpc.vpc_id)
egress_rules = var.app_egress_rules
ingress_rules = var.app_ingress_rules
cidr_blocks = var.app_cidr_blocks
common-tags = local.common-tags
}
module "database_sg" {
source = "../../modules/security"
create_sg = var.create_sg
vpc_id = one(module.sre_vpc.vpc_id)
sg_name = var.db_sg_name
name_suffix = var.name_suffix
environment = local.common-tags.environment
egress_rules = var.db_egress_rules
ingress_rules = var.db_ingress_rules
ingress_self_sg = true
common-tags = local.common-tags
}
################################
# List of Security Group Rules #
################################
variable "app_ingress_rules" {
type = map(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
default = {
SSH = {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
HTTP = {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
HTTPS = {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
variable "app_egress_rules" {
type = map(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
default = {
ALLOW_ALL = {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
variable "db_ingress_rules" {
type = map(object({
from_port = number
to_port = number
protocol = string
}))
default = {
MYSQL = {
from_port = 3306
to_port = 3306
protocol = "tcp"
},
HTTPS = {
from_port = 443
to_port = 443
protocol = "tcp"
}
}
}
variable "db_egress_rules" {
type = map(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
default = {
ALLOW_ALL = {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
Child Module
################################
# Create Securiy Group & Rules #
################################
resource "aws_security_group" "app_sg" {
for_each = var.create_sg ? toset(var.sg_name) : []
name = each.key
vpc_id = var.vpc_id
dynamic "ingress" {
for_each = var.ingress_rules != {} ? toset(values(var.ingress_rules)) : []
content {
from_port = ingress.value["from_port"]
to_port = ingress.value["to_port"]
protocol = ingress.value["protocol"]
cidr_blocks = ingress.value["cidr_blocks"]
security_groups = var.security_groups
self = var.ingress_self_sg
}
}
dynamic "egress" {
for_each = var.egress_rules != {} ? toset(values(var.egress_rules)) : []
content {
from_port = egress.value["from_port"]
to_port = egress.value["to_port"]
protocol = egress.value["protocol"]
cidr_blocks = egress.value["cidr_blocks"]
security_groups = var.security_groups
self = var.egress_self_sg
}
}
tags = merge(
var.common-tags,
{
"Name" = "${each.key}-${lower(var.environment)}"
}
)
}
// Variables
variable "create_sg" {
}
variable "vpc_id" {
}
variable "environment" {
}
variable "name_suffix" {
}
variable "sg_name" {
}
variable "common-tags" {
}
variable "ingress_rules" {
type = any
default = {}
}
variable "egress_rules" {
type = any
default = {}
}
variable "security_groups" {
type = list(string)
default = []
}
variable "ingress_self_sg" {
type = bool
default = false
}
variable "egress_self_sg" {
type = bool
default = false
}
Your var.db_ingress_rules does not have cidr_blocks. You have to add it there, e.g.:
variable "db_ingress_rules" {
type = map(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
}))
default = {
MYSQL = {
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
},
HTTPS = {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
I'm trying to write a Terraform module for AWS Security Groups with the dynamic block, but I'm having this error:
│
│ on main.tf line 17, in module "security_group":
│ 17: ingress = {
│
│ The argument "ingress" was already set at main.tf:8,5-12. Each argument may be set only once.
I've followed the documentation but I'm still having the error
I'm using Terraform 0.15.1 and AWS provider version 3.38.0
Here is my code
./modules/security_group/main.tf
resource "aws_security_group" "main" {
.......
dynamic "ingress" {
for_each = var.ingress
content {
description = ingress.value["description"]
from_port = ingress.value["from_port"]
to_port = ingress.value["to_port"]
protocol = ingress.value["protocol"]
cidr_blocks = ingress.value["cidr_blocks"]
ipv6_cidr_blocks = ingress.value["ipv6_cidr_blocks"]
}
}
.......
}
./modules/security_group/variables.tf
variable "ingress" {
description = ""
type = object({
description = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
ipv6_cidr_blocks = list(string)
})
default = {
description = ""
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = []
ipv6_cidr_blocks = []
}
}
./main.tf
module "security_group" {
source = "./modules/security_group"
name = "${var.project}-sg"
description = "security group testing"
vpc_id = "my-vpc"
ingress = {
description = ""
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = []
ipv6_cidr_blocks = []
}
ingress = {
description = ""
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = []
ipv6_cidr_blocks = []
}
}
You have ingress arguments. I think you want to have one as a list:
variable "ingress" {
description = ""
type = list(object({
description = string
from_port = number
to_port = number
protocol = string
cidr_blocks = list(string)
ipv6_cidr_blocks = list(string)
}))
default = [{
description = ""
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = []
ipv6_cidr_blocks = []
}
}]
module "security_group" {
source = "./modules/security_group"
name = "${var.project}-sg"
description = "security group testing"
vpc_id = "my-vpc"
ingress = [{
description = ""
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = []
ipv6_cidr_blocks = []
}, {
description = ""
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = []
ipv6_cidr_blocks = []
}]
}
Using Terraform version 12, I am attempting to create some AWS security group rules.
I need to create x number of rules which may have different from and to ports.
These rules need to be create for each security group returned from the sg_groups data lookup.
So I have a nested list/map.
I think this is doable using Terraform's for_each and for loop function but I struggling to get my head around how to make this work.
Can anybody help me getting looping syntax correct.
Note: The format of the sg_rules map is not set in stone and can be formatted in any way that works best.
variable "sg_rules" = {
type = map
default = {
80 = {
protocol = "tcp"
from_port = 80
to_port = 80
},
443 = {
protocol = "tcp"
from_port = 443
to_port = 443
},
service_ports = {
protocol = "tcp"
from_port = 60000
to_port = 60500
}
}
}
data "aws_security_groups" "sg_groups" {
filter {
name = "group-name"
values = var.sg_names
}
}
Here is an example in which I have created the list of AWS Security Groups using nested for_each.
One for_each for creating a list of AWS Security Groups and another for creating dynamic Ingress and Egress Rules.
main.tf
resource "aws_security_group" "security-groups" {
# Dynamic number of Security Groups
for_each = var.security_group_configurations.security_groups
name = each.value.name
description = each.value.description
vpc_id = var.vpc_id
# Dynamic number of Ingress Rules
dynamic ingress {
for_each = var.security_group_configurations.security_groups[each.key].ingress_rules
content {
description = ingress.value.description
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = lookup(ingress.value, "cidr_blocks", [])
ipv6_cidr_blocks = lookup(ingress.value, "ipv6_cidr_blocks", [])
security_group_id = lookup(ingress.value, "security_group_id", "")
}
}
# Dynamic number of Egress Rules
dynamic egress {
for_each = var.security_group_configurations.security_groups[each.key].egress_rules
content {
description = egress.value.description #Here the 'egress' is the dynamic egress block
from_port = egress.value.from_port
to_port = egress.value.to_port
protocol = egress.value.protocol
cidr_blocks = lookup(ingress.value, "cidr_blocks", [])
ipv6_cidr_blocks = lookup(ingress.value, "ipv6_cidr_blocks", [])
security_group_id = lookup(ingress.value, "security_group_id", "")
}
}
tags = each.value.tags
}
variables.tf
variable "security_group_configurations" {
description = "All Security_Groups related configuration"
}
variable "vpc_id" {
description = "Vpc Id for security_groups"
}
example.tfvars
vpc_id = "vpc-0be6071d37dsd985b"
security_group_configurations = {
security_groups = {
#--------------------->> Security Group 0 <-------------------------------------------
"0" = {
name = "security_group_0"
description = "security_group_0"
# Ingress Rules
ingress_rules = {
# Ingress Rule 0
0 = {
description = "TLS from Public Internet"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
},
# Ingress Rule 1
1 = {
description = "SSH from Public Internet"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
},
}
# Egress Rules
egress_rules = {
# Egress Rule 0
0 = {
description = "Allow all traffic to outside"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
},
# Egress Rule 1
##############
}
# Tags for Security Group 0
tags = {
Name = "security_group_0"
}
},
#--------------------->> Security Group 1 <-------------------------------------------
"1" = {
name = "security_group_1"
description = "security_group_1"
# Ingress Rules
ingress_rules = {
# Ingress Rule 0
0 = {
description = "TLS from Public Internet"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
},
# Ingress Rule 1
1 = {
description = "SSH from Public Internet"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
},
}
# Egress Rules
egress_rules = {
# Egress Rule 0
0 = {
description = "Allow all traffic to outside"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
},
# Egress Rule 1
####
####
}
# Tags for Security Group 1
tags = {
Name = "security_group_1"
}
}
#--------------------->> Security Group 2 <-------------------------------------------
#######
#######
}
}
In typical fashion as soon as I ask for help I end up figuring it out myself, or at least one way of doing it. Here is what I came up with, if anyone has any better ideas please feel free to say
variable "sg_rules" = {
type = map
default = [
{
protocol = "tcp"
from_port = 80
to_port = 80
},
{
protocol = "tcp"
from_port = 443
to_port = 443
},
{
protocol = "tcp"
from_port = 60000
to_port = 60500
}
}
}
locals {
gw_to_mx_rules = [
for pair in setproduct(data.aws_security_groups.sg_groups.ids, var.sg_rules) : {
sg = pair[0]
type = pair[1].type
protocol = pair[1].protocol
from_port = pair[1].from_port
to_port = pair[1].to_port
}
]
}
data "aws_security_groups" "sg_groups" {
filter {
name = "group-name"
values = var.sg_names
}
}
resource "aws_security_group_rule" "gw_to_mx" {
for_each = { for rule in local.gw_to_mx_rules : "${rule.type}.${rule.from_port}.${rule.to_port}.${rule.protocol}.${rule.sg}" => rule }
description = "MX Communication"
type = each.value.type
from_port = each.value.from_port
to_port = each.value.to_port
protocol = each.value.protocol
source_security_group_id = each.value.sg
security_group_id = aws_security_group.waf_instance_sg.id
}