Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Public Access to ALB #50

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
37 changes: 37 additions & 0 deletions _variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,31 @@ variable "alb_sg_allow_test_listener" {
description = "Whether to allow world access to the test listeners"
}

variable "alb_sg_custom_cidr_blocks" {
default = ["0.0.0.0/0"]
description = "Block public access to ALB and stick to these CIDR blocks only"
}

variable "alb_additional_sg" {
default = []
description = "pass addition list of security groups to add to ALB"
}

variable "alb_sg_allow_cloudfront" {
default = false
description = "Whether to allow Cloudfront IP range to access"
}

variable "alb_sg_allow_api_gateway" {
default = false
description = "Whether to allow API Gateway IP range to access"
}

variable "alb_sg_allow_api_gateway_region" {
default = ""
description = "Use this region to allow API Gateway IP range"
}

variable "alb_sg_allow_egress_https_world" {
default = true
description = "Whether to allow ALB to access HTTPS endpoints - needed when using OIDC authentication"
Expand Down Expand Up @@ -366,4 +391,16 @@ variable "container_insights" {
type = bool
default = false
description = "Enables CloudWatch Container Insights for a cluster."
}

variable "enable_managed_draining" {
description = "Enable managed draining for ECS instances and add AmazonECSManaged tag"
type = bool
default = true
}

variable "enable_managed_termination_protection" {
description = "Enable managed draining for ECS instances and add AmazonECSManaged tag"
type = bool
default = false
}
9 changes: 6 additions & 3 deletions alb.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ resource "aws_lb" "ecs" {
drop_invalid_header_fields = var.alb_drop_invalid_header_fields
enable_deletion_protection = var.alb_enable_deletion_protection

security_groups = [
aws_security_group.alb[0].id,
]
security_groups = compact(
concat(try(aws_security_group.from_cloudfront.*.id, []),
try(var.alb_additional_sg,[]),
[ aws_security_group.alb[0].id,
try(aws_security_group.from_api_gateway[0].id, "")
]))

idle_timeout = 400

Expand Down
15 changes: 13 additions & 2 deletions asg.tf
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,19 @@ resource "aws_autoscaling_group" "ecs" {
propagate_at_launch = true
}

dynamic "tag" {
for_each = var.enable_managed_draining ? [1] : []
content {
key = "AmazonECSManaged"
value = ""
propagate_at_launch = true
}
}

target_group_arns = var.target_group_arns
health_check_grace_period = var.autoscaling_health_check_grace_period
default_cooldown = var.autoscaling_default_cooldown

lifecycle {
create_before_destroy = true
}
Expand All @@ -53,7 +63,8 @@ resource "aws_ecs_capacity_provider" "ecs_capacity_provider" {

auto_scaling_group_provider {
auto_scaling_group_arn = aws_autoscaling_group.ecs[0].arn
managed_termination_protection = "DISABLED"
managed_termination_protection = var.enable_managed_termination_protection ? "ENABLED" : "DISABLED"
managed_draining = var.enable_managed_draining ? "ENABLED" : "DISABLED"

managed_scaling {
maximum_scaling_step_size = 10
Expand All @@ -62,4 +73,4 @@ resource "aws_ecs_capacity_provider" "ecs_capacity_provider" {
target_capacity = var.asg_target_capacity
}
}
}
}
4 changes: 2 additions & 2 deletions sg-alb.tf
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ resource "aws_security_group_rule" "https_from_world_to_alb" {
to_port = 443
protocol = "tcp"
security_group_id = aws_security_group.alb[0].id
cidr_blocks = ["0.0.0.0/0"]
cidr_blocks = var.alb_sg_custom_cidr_blocks
}

resource "aws_security_group_rule" "https_test_listener_from_world_to_alb" {
Expand All @@ -43,7 +43,7 @@ resource "aws_security_group_rule" "https_test_listener_from_world_to_alb" {
to_port = 8443
protocol = "tcp"
security_group_id = aws_security_group.alb[0].id
cidr_blocks = ["0.0.0.0/0"]
cidr_blocks = var.alb_sg_custom_cidr_blocks
}


Expand Down
61 changes: 61 additions & 0 deletions sg-aws-iprange.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
data "aws_ip_ranges" "cloudfront" {
regions = ["global"]
services = ["cloudfront"]
}

data "aws_ip_ranges" "api_gateway" {
regions = compact([data.aws_region.current.name,try(var.alb_sg_allow_api_gateway_region, "")])
services = ["api_gateway"]
}

locals {
ip_chunks = chunklist(data.aws_ip_ranges.cloudfront.cidr_blocks, 50)
}

resource "aws_security_group" "from_cloudfront" {
count = var.alb && var.alb_sg_allow_cloudfront ? length(local.ip_chunks) : 0
name = "from-cloudfront-${var.name}-${count.index}"
description = "SG for Request from Cloudfront"
vpc_id = var.vpc_id

dynamic "ingress" {
for_each = local.ip_chunks[count.index]

content {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [ingress.value]
}
}

tags = {
Name = "from-cloudfront-${var.name}-${count.index}"
}

lifecycle {
create_before_destroy = true
}
}

resource "aws_security_group" "from_api_gateway" {
count = var.alb && var.alb_sg_allow_api_gateway ? 1 : 0
name = "from-api-gateway-${var.name}"
description = "SG for Request from API Gateway"
vpc_id = var.vpc_id

ingress {
from_port = "443"
to_port = "443"
protocol = "tcp"
cidr_blocks = data.aws_ip_ranges.api_gateway.cidr_blocks
}

tags = {
Name = "from-api-gateway-${var.name}"
}

lifecycle {
create_before_destroy = true
}
}
14 changes: 14 additions & 0 deletions userdata.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ echo "vm.max_map_count=262144" >> /etc/sysctl.conf
echo "fs.file-max=65536" >> /etc/sysctl.conf
/sbin/sysctl -p /etc/sysctl.conf

function checkECSregistration {
logger -s "ecs Check if there are any running Docker containers"
# Check if there are any running Docker containers
sleep 1200
docker_container_count=$(docker ps -q | wc -l)
ecs_registration=$(curl -s http://localhost:51678/v1/metadata | grep ${tf_cluster_name} | wc -l)
# If there are no running Docker containers and ECS agent is still not registered, terminate the instance
if [ "$docker_container_count" -le "1" ] && [ $ecs_registration -eq "0" ]; then
logger -s "No running Docker containers found and ECS agent is not registered. Terminating the instance..."
shutdown -h now
fi
}

checkECSregistration &

echo "### INSTALL PACKAGES"
yum update -y
Expand Down