1

i think I should be able to do something like this. but the map of ports, protocal, and cidrs is wrong... how do I make a map of lists and interate over the map.

variable "master-sg-ingress-ports" {
  //depends_on [aws_security_group.master-lb-sg, aws_security_group.worker-sg]
  description = "List of port numbers for specific security group"
  type        = map(any)

  //  format should be [ sg1 =  [from_port, to_port, protocol, from_ip_cidr] ]  ]
  default     = [ "ingress1" =  [80, 80, "TCP", "0.0.0/0"],
                  "ingress2" =  [80, 80, "TCP", "::0/0"],
                  "ingress3" =  [443, 80, "TCP", "0.0.0.0/0"],
                  "ingress4" =  [443, 80, "TCP", "::0/0"],
                  "ingress5 "=  [0, 0, "-1", "172.30.0.0/16"],]
}

resource "aws_security_group" "master_sg" {
  depends_on  = [aws_security_group.master_lb_sg, aws_security_group.worker_sg]
  provider    = aws.region_master
  name        = "master-sg"
  description = "security group for Jenkins master"
  vpc_id      = aws_vpc.vpc_master.id


  dynamic "ingress" {
    # this for_each is not identical to for_each in line 21
    for_each = toset(var.master-sg-ingress-ports) # iterator can be (need to be) configured
    iterator = it                                 # set the name of the iterator, which can be any name, but "each" (!!)
    content {
      from_port   = it[0].value
      to_port     = it[1].value
      protocol    = it[2].value
      cidr_blocks = [it[3].value]
    }
  }
}

terraform init is giving me the following with a underline under ingress1

The Terraform configuration must be valid before initialization so that
Terraform can determine which modules and providers need to be installed.
╷
│ Error: Invalid default value for variable
│ 
│   on security_groups.tf line 64, in variable "master-sg-ingress-ports":
│   64:   default     = [ "ingress1" =  [80, 80, "TCP", "0.0.0/0"],
│   65:                   "ingress2" =  [80, 80, "TCP", "::0/0"],
│   66:                   "ingress3" =  [443, 80, "TCP", "0.0.0.0/0"],
│   67:                   "ingress4" =  [443, 80, "TCP", "::0/0"],
│   68:                   "ingress5 "=  [0, 0, "-1", "172.30.0.0/16"],].
╵```
Marcin
  • 215,873
  • 14
  • 235
  • 294
peter cooke
  • 987
  • 3
  • 10
  • 28

1 Answers1

2

The correct default value is a map, not a list of maps as you have now. So it should be:

variable "master-sg-ingress-ports" {
 
  description = "List of port numbers for specific security group"
  type        = map(any)

  default     = { "ingress1" =  [80, 80, "TCP", "0.0.0.0/0"],
                  "ingress2" =  [80, 80, "TCP", "::/0"],
                  "ingress3" =  [443, 80, "TCP", "0.0.0.0/0"],
                  "ingress4" =  [443, 80, "TCP", "::/0"],
                  "ingress5 "=  [0, 0, "-1", "172.30.0.0/16"]}
}

Update for master_sg:

resource "aws_security_group" "master_sg" {
 # depends_on  = [aws_security_group.master_lb_sg, aws_security_group.worker_sg]
 # provider    = aws.region_master
  name        = "master-sg"
  description = "security group for Jenkins master"
  vpc_id      = data.aws_vpc.default.id


  dynamic "ingress" {
    # this for_each is not identical to for_each in line 21
    for_each = var.master-sg-ingress-ports 
    content {
      from_port   = ingress.value[0]
      to_port     = ingress.value[1]
      protocol    = ingress.value[2]
      cidr_blocks = [ingress.value[3]]
    }
  }
}
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • well that is 1/2 of the problem now Terraform does not like the itterator assignment. getting "The given key does not identify an element in this collection value" on rom_port = it[0].value – peter cooke Jul 03 '21 at 08:51
  • @petercooke I updated the answer, but your code will not work as your are **mixing** ipv4 and ipv6 and you have incorect CIDR and port ranges anyway. You can't mix ip4 and ip6 this way. For ipv6 you must use `ipv6_cidr_blocks`, not `cidr_blocks`. I would suggest making new question how to deal with that, or simply remove ipv6 if you don't need it. – Marcin Jul 03 '21 at 09:09
  • just an fyi. it does not like the " [443,80" the port 443 needs to be 443,443 – peter cooke Jul 03 '21 at 17:18
  • darn it getting " Error authorizing security group ingress rules: InvalidParameterValue: CIDR block ::/0 is malformed " there is a lot google on this no real solution – peter cooke Jul 03 '21 at 17:22
  • @petercooke I wrote that you can't mix ipv4 with ipv6. ::/0 is ipv6. – Marcin Jul 03 '21 at 21:36