I am setting up the AWS infrastructure using Terraform. One of components is ElasticBeanstalk application/environment with a load balancer and auto-scaling group. I don't want to expose the endpoint to entire Internet but just to the limited list of IP addresses. For that purpose I create the security group with proper inbound rules and assign it to the load balancer. But after script was applied, the load balancer has two security groups - one mine and second one - default, that allows HTTP traffic from any where. As temp workaround I manually remove the inbound rule for the default SG. Such approach is not acceptable as long-term solution since I want full automation of infrastructure setup (without any human interaction).
Here is my config:
resource "aws_elastic_beanstalk_environment" "abc_env" {
  name = "abc-${var.environment_name}"
  application = "${aws_elastic_beanstalk_application.abc-service.name}"
  solution_stack_name = "64bit Amazon Linux 2016.09 v2.3.0 running Python 3.4"
  cname_prefix = "abc-${var.environment_name}"
  tier = "WebServer"
  wait_for_ready_timeout = "30m"
  setting {
    name = "InstanceType"
    namespace = "aws:autoscaling:launchconfiguration"
    value = "m3.medium"
  }
  setting {
    name = "SecurityGroups"
    namespace = "aws:elb:loadbalancer"
    value = "${var.limited_http_acccess_id}"
  }
  setting {
    name = "VPCId"
    namespace = "aws:ec2:vpc"
    value = "${var.vpc_id}"
  }
  setting {
    name = "Subnets"
    namespace = "aws:ec2:vpc"
    value = "${var.public_net_id}"
  }
  setting {
    name = "AssociatePublicIpAddress"
    namespace = "aws:ec2:vpc"
    value = "true"
  }
  setting {
    name = "ELBSubnets"
    namespace = "aws:ec2:vpc"
    value = "${var.public_net_id}"
  }
  setting {
    name = "ELBScheme"
    namespace = "aws:ec2:vpc"
    value = "external"
  }
  setting {
    name = "MinSize"
    namespace = "aws:autoscaling:asg"
    value = "2"
  }
  setting {
    name = "MaxSize"
    namespace = "aws:autoscaling:asg"
    value = "4"
  }
  setting {
    name = "Availability Zones"
    namespace = "aws:autoscaling:asg"
    value = "Any 2"
  }
  setting {
    name = "CrossZone"
    namespace = "aws:elb:loadbalancer"
    value = "true"
  }
  setting {
    name = "Unit"
    namespace = "aws:autoscaling:trigger"
    value = "Percent"
  }
  setting {
    name = "MeasureName"
    namespace = "aws:autoscaling:trigger"
    value = "CPUUtilization"
  }
  setting {
    name = "LowerThreshold"
    namespace = "aws:autoscaling:trigger"
    value = "20"
  }
  setting {
    name = "UpperThreshold"
    namespace = "aws:autoscaling:trigger"
    value = "80"
  }
  setting {
    name = "Period"
    namespace = "aws:autoscaling:trigger"
    value = "5"
  }
  setting {
    name = "UpperBreachScaleIncrement"
    namespace = "aws:autoscaling:trigger"
    value = "1"
  }
  setting {
    name = "LowerBreachScaleIncrement"
    namespace = "aws:autoscaling:trigger"
    value = "-1"
  }
  setting {
    name = "Notification Endpoint"
    namespace = "aws:elasticbeanstalk:sns:topics"
    value = "${var.notification_email}"
  }
  tags = "${merge(var.default_tags, map("Name", "abc environment"))}"
}
So the question is: how can I limit access to my load balancer without manual interaction with AWS (only using Terraform script)?
[UPDATE] Here is my network config
resource "aws_vpc" "main_vpc" {
  cidr_block = "${var.vpc_cidr_block}"
  enable_dns_hostnames = true
}
resource "aws_subnet" "public_network" {
  vpc_id = "${aws_vpc.main_vpc.id}"
  cidr_block = "${var.public_network_cidr_block}"
}
resource "aws_internet_gateway" "gateway" {
  vpc_id = "${aws_vpc.main_vpc.id}"
}
resource "aws_route_table" "public" {
  vpc_id = "${aws_vpc.main_vpc.id}"
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = "${aws_internet_gateway.gateway.id}"
  }
}
resource "aws_route_table_association" "public" {
  route_table_id = "${aws_route_table.public.id}"
  subnet_id = "${aws_subnet.public_network.id}"
}
resource "aws_security_group" "limited_http_acccess" {
  name = "limited_http_acccess"
  description = "This security group allows to access resources within VPC from specified IP addresses"
  vpc_id = "${aws_vpc.main_vpc.id}"
  ingress {
    from_port = 80
    to_port = 80
    protocol = "TCP"
    cidr_blocks = ["${split(",", var.allowed_cidr_list)}"]
  }
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
                According to AWS docs ManagedSecurityGroup needs to be added to ElasticBeansstalk config in order to prevent usage of default security group.
So adding of the following lines to my aws_elastic_beanstalk_environment fixed the issue
  setting {
    name = "ManagedSecurityGroup"
    namespace = "aws:elb:loadbalancer"
    value = "${var.limited_http_acccess_id}"
  }
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With