nirkov
nirkov

Reputation: 809

How can I create terraform aws_security_group with multiple eip and ec2 instances?

I'm trying to create the instances according to the following code -

resource "aws_instance" "ec2" {
  ami = "ami-0fe0b2cf0e1f25c8a"
  instance_type = var.ec2_instance_type
  count = var.number_of_instances

  tags = {
    Name = "ec2_instance_${count.index}"
  }
}

resource "aws_eip" "lb" {
  vpc = true
  count = var.number_of_instances
}

resource "aws_eip_association" "eic_assoc" {
  instance_id = aws_instance.ec2[count.index].id
  allocation_id = aws_eip.lb[count.index].id
  count = var.number_of_instances
}

resource "aws_security_group" "allow_tls" {
  name = "first-security-group-created-by-terraform"
  count = var.number_of_instances
  ingress {
      from_port = var.security_group_port
      to_port = var.security_group_port
      protocol = var.security_group_protocol
      cidr_blocks = ["${aws_eip.lb[count.index].public_ip}/32"]
  }
}

And got the following error -

Error: creating Security Group (first-security-group-created-by-terraform): InvalidGroup.Duplicate: The security group 'first-security-group-created-by-terraform' already exists for VPC 'vpc-0fb3457c89d86e916'

Probably because this is not the right way to create the aws_security_group when there are multiple instances of eip and ec2.

What is the right way to do that?

Upvotes: 0

Views: 252

Answers (1)

Mark B
Mark B

Reputation: 200486

You are creating multiple security groups, but giving them all exactly the same name. The name needs to be unique for each security group. You could fix it like this:

resource "aws_security_group" "allow_tls" {
  count = var.number_of_instances
  name  = "first-security-group-created-by-terraform-${count.index}"
  ingress {
      from_port = var.security_group_port
      to_port = var.security_group_port
      protocol = var.security_group_protocol
      cidr_blocks = ["${aws_eip.lb[count.index].public_ip}/32"]
  }
}

One way to create a single security group with multiple ingress rules is to create the group without any ingress blocks, and then create the ingress rules separately:

resource "aws_security_group" "allow_tls" {
  name  = "first-security-group-created-by-terraform"
}

resource "aws_security_group_rule" "allow_tls_rules" {
  count = var.number_of_instances

  type              = "ingress"
  from_port         = var.security_group_port
  to_port           = var.security_group_port
  protocol          = var.security_group_protocol
  cidr_blocks       = ["${aws_eip.lb[count.index].public_ip}/32"]
  security_group_id = aws_security_group.allow_tls.id
}

Upvotes: 2

Related Questions