skip to Main Content

I have an ec2 instance defined in terraform along with some security rules.

These are the security rules:

resource "aws_security_group" "ec2_web" {
  name        = "${var.project_name}_${var.env}_ec2_web"
  description = "ec2 instances that serve to the load balancer"
  vpc_id      = aws_vpc.main.id
}
resource "aws_security_group_rule" "ec2_web_http" {
  type              = "egress"
  from_port         = 80
  to_port           = 80
  protocol          = "tcp"
  # cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.ec2_web.id
  source_security_group_id = aws_security_group.elb.id
}
resource "aws_security_group_rule" "ec2_web_ssh" {
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["${var.ip_address}/32"]
  security_group_id = aws_security_group.ec2_web.id
}

I’m trying to simply add another security rule:

resource "aws_security_group_rule" "ec2_web_ssh_test" {
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["${var.ip_address}/32"]
  security_group_id = aws_security_group.ec2_web.id
}

And terraform wants to completely replace the security group, and that cascades into completely replacing the ec2 instance.

I’m modifying the .tf file and then running:

terraform apply

EDIT:

The security group itself seems completely unrelated. When I do "plan", I get the output:

  # aws_instance.ec2 must be replaced
-/+ resource "aws_instance" "ec2" {
...
      ~ security_groups                      = [ # forces replacement
          + "sg-0befd5d21eee052ad",
        ]

The ec2 instance is created with:

resource "aws_instance" "ec2" {
  
  ami           = "ami-0b5eea76982371e91"
  instance_type = "t3.small"
  key_name      = "${var.project_name}"

  depends_on = [aws_internet_gateway.main]

  user_data     = <<EOF
#!/bin/bash
sudo amazon-linux-extras install -y php8.1 mariadb10.5
sudo yum install -y httpd mariadb php8.1 php8.1-cli
sudo systemctl start httpd
sudo systemctl enable httpd
echo 'yup' | sudo tee /var/www/html/index.html
echo '<?php echo phpinfo();' | sudo tee /var/www/html/phpinfo.php
  EOF
  tags = {
    Name = "${var.project_name}_${var.env}_ec2"
  }
  root_block_device {
    volume_size = 8 # GB
    volume_type = "gp3"
  }
  security_groups = [aws_security_group.ec2_web.id]
  # vpc_security_group_ids = [aws_security_group.main.id]
  subnet_id = aws_subnet.main1.id
}

If I comment out

# security_groups = [aws_security_group.bake.name]

I do not get any errors.

3

Answers


  1. Before apply please run terraform apply -refresh-only then your main problem is you can not define same rule with different terraform id.

    When you apply new changes for ec2_web_ssh_test AWS will complain about

    │Error: [WARN] A duplicate Security Group rule was found on (sg-xxxxxx). This may be
    │ a side effect of a now-fixed Terraform issue causing two security groups with
    │ identical attributes but different source_security_group_ids to overwrite each
    │ other in the state
    

    Then you will get this error from AWS api

    Error: InvalidPermission.Duplicate: the specified rule "peer: xxx.xxx.xxx.xxx/32, TCP, from port: 22, to port: 22, ALLOW" already exists
    
    Login or Signup to reply.
  2. With Terraform it compares the current state of your configuration with the new state which will contain the new rule you are adding. Here current state is not same as the desired state with new rule you are adding.

    Hence with two different states, Terraform is trying to destroy the EC2 instances and trying to build new instances with newly added rules state.

    This can be avoided with using terraform import command that will import the existing resources to your terraform state and then make changes to it.

    Login or Signup to reply.
  3. This happens because security_groups can only be used EC2-Classic (legacy instances) and a default VPC. For everything else you must use vpc_security_group_ids.

    In your cause you are using custom VPC called main, thus you must be using vpc_security_group_ids, not security_groups.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search