Search code examples
amazon-web-servicesterraformterraform-provider-aws

Terraform shows `InvalidGroup.NotFound` while creating an EC2 instance


I am trying to deploy EC2 instances using Terrafom and I can see the following error:

Error: Error launching source instance: InvalidGroup.NotFound: The security group 'prod-web-servers-sg' does not exist in VPC 'vpc-db3a3cb3'

Here is the Terraform template I'm using:

resource "aws_default_vpc" "default" {
}

resource "aws_security_group" "prod-web-servers-sg" {
name        = "prod-web-servers-sg"
description = "security group for production grade web servers"
vpc_id      = "${aws_default_vpc.default.id}"

ingress {
from_port   = 80
to_port     = 80
protocol    = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port   = 443
to_port     = 443
protocol    = "tcp"
cidr_blocks = ["0.0.0.0/0"]
  }
}

#Subnet

 resource "aws_subnet" "private_subnet" {
 vpc_id     = "${aws_default_vpc.default.id}"
 cidr_block = "172.31.0.0/24"
 availability_zone = "ap-south-1a"
 }

 resource "aws_instance" "prod-web-server" {
 ami           = "ami-04b1ddd35fd71475a"
 count    = 2
 key_name = "test_key"
 instance_type = "r5.large"
 security_groups = ["prod-web-servers-sg"]
 subnet_id = "${aws_subnet.private_subnet.id}"
  }

Solution

  • You have a race condition there because Terraform doesn't know to wait until the security group is created before creating the instance.

    To fix this you should interpolate the aws_security_group.prod-web-servers-sg.id into aws_instance.prod-web-server resource so that it can work out the dependency chain between the resources. You should also use vpc_security_group_ids instead of security_groups as mentioned in the aws_instance resource documentation:

    security_groups - (Optional, EC2-Classic and default VPC only) A list of security group names (EC2-Classic) or IDs (default VPC) to associate with.

    NOTE: If you are creating Instances in a VPC, use vpc_security_group_ids instead.

    So you should have something like the following:

    resource "aws_default_vpc" "default" {}
    
    resource "aws_security_group" "prod-web-servers-sg" {
      name        = "prod-web-servers-sg"
      description = "security group for production grade web servers"
      vpc_id      = aws_default_vpc.default.id
    
      ingress {
        from_port   = 80
        to_port     = 80
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
      ingress {
        from_port   = 443
        to_port     = 443
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    }
    
    #Subnet
    
    resource "aws_subnet" "private_subnet" {
      vpc_id            = aws_default_vpc.default.id
      cidr_block        = "172.31.0.0/24"
      availability_zone = "ap-south-1a"
    }
    
    resource "aws_instance" "prod-web-server" {
      ami                    = "ami-04b1ddd35fd71475a"
      count                  = 2
      key_name               = "test_key"
      instance_type          = "r5.large"
      vpc_security_group_ids = [aws_security_group.prod-web-servers-sg.id]
      subnet_id              = aws_subnet.private_subnet.id
    }