Get AppScaled ECS Tasks served by AWS Network Load Balancer

This article is intended to be a quick and dirty snippet for anyone going to through the struggle of getting your ECS service, which might have one or more containers running the same App (being part of an Auto Scaling Group), with a Network Load Balancer (instead of the more common ELB or ALB).

ECS Service/Task Definition

Another particularity of this implementation is that I also decided to use the ECS task’s network mode as awsvpc. In the case that you are not acquainted with this new option, this means that:

  • Your container will get its own network interface and its own IP address;
  • The Host port and the Container port need to be the same, since there is not middleware managing port match between the two entities.

The cherry on top is that the ECS Service now has the option of automatically registering and deregistering LB targets by their IP address, which fits perfectly on the intention described.

Network Load Balancer

This post isn’t concretely about describing the technical details of what is a Network Load Balancer but about the caveats of using it in this scenario: because NLB is a layer 4 load balancer, you won’t be able to define Security Groups at the NLB level. Instead, you’ll have to make sure you make your tasks/containers secure by attaching the security groups to them – remember that with the awsvpc network mode, each container will get its own NIC.


As for the actual code snippet to support what I’m trying to achieve:

# Following assumes you already have an ECS Cluster in place
resource "aws_lb" "this" {
name = "some-service-nlb"
load_balancer_type = "network"
internal = false
idle_timeout = "150"
subnets = "${var.subnet_list}"
resource "aws_ecs_task_definition" "this" {
family = "${var.task_family_name}"
task_role_arn = "${var.task_definition_role_arn}"
network_mode = "awsvpc"
container_definitions = <<EOF
"cpu": 128,
"essential": true,
"image": "postgres:latest",
"memory": 512,
"memoryReservation": 512,
"name": "postgres",
"portMappings": [
"hostPort": ${var.container_port},
"protocol": "tcp",
"containerPort": ${var.container_port}
resource "aws_ecs_service" "this" {
name = "${var.app_name}-service"
task_definition = "${var.task_family_name}:latests"
cluster = "${var.ecs_cluster_id}"
desired_count = "${var.service_task_count}"
network_configuration {
subnets = "${var.subnet_list}"
security_groups = ["${var.task_service_security_group}"]
deployment_maximum_percent = "${var.deployment_max_percent}"
deployment_minimum_healthy_percent = "${var.deployment_min_healthy_percent}"
health_check_grace_period_seconds = "${var.health_check_grace_period}"
scheduling_strategy = "REPLICA"
load_balancer {
target_group_arn = "${aws_lb_target_group.this.arn}"
container_name = "${var.container_name}"
container_port = "${var.container_port}"
resource "aws_lb_target_group" "this" {
name = "${var.environment}${var.base_name}-ecs-current"
port = "${var.container_port}"
protocol = "TCP"
vpc_id = "${var.vpc_id}"
target_type = "ip"
health_check {
protocol = "${var.lb_tg_health_check_protocol}"
resource "aws_lb_listener" "this" {
load_balancer_arn = "${aws_lb.this.arn}"
port = "${var.container_port}"
protocol = "TCP"
default_action {
type = "forward"
target_group_arn = "${aws_lb_target_group.this.arn}"

view raw

hosted with ❤ by GitHub

If you are familiar with Terraform and AWS services, the noteworthy parts part of the above code are:

  • The aws_lb is of type “network”
  • The host port and the container port are the same in the task definition
  • awsvpc in the network mode of the tak
  • We make the ECS service responsible for registering targets with the “load_balancer” section.
  • The target_type of the target group must be of type IP.
  • The security group to take into consideration here would be directly in the security_groups section of the aws_ecs_service.

And… that’s it!




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s