Skip to content

Commit

Permalink
Merge pull request #15 from trussworks/mk-nlb-support
Browse files Browse the repository at this point in the history
Add support for associating an ECS service with a NLB.
  • Loading branch information
Michael Kania authored Sep 12, 2018
2 parents 821a508 + 55ed267 commit 1e491e1
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 18 deletions.
37 changes: 32 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Creates the following resources:
* Security Groups for the ECS service.
* ECS service.
* Task definition using `nginx:stable` (see below).
* Configurable associations with Network Load Balancers (NLB) and Application Load Balancers (ALB).

We create an initial task definition using the `nginx:stable` image as a way
to validate the initial infrastructure is working: visiting the site shows
Expand All @@ -15,6 +16,30 @@ definitions going forward, not Terraform.

## Usage

### ECS service associated with an Application Load Balancer (ALB)

```hcl
module "app_ecs_service" {
source = "../../modules/aws-ecs-service"
name = "app"
environment = "prod"
ecs_cluster_arn = "${module.app_ecs_cluster.ecs_cluster_arn}"
ecs_vpc_id = "${module.vpc.vpc_id}"
ecs_subnet_ids = "${module.vpc.private_subnets}"
tasks_desired_count = 2
tasks_minimum_healthy_percent = 50
tasks_maximum_percent = 200
associate_alb = true
alb_security_group = "${module.security_group.id}"
lb_target_group = "${module.target_group.id}"
}
```

### ECS Service associated with a Network Load Balancer(NLB)

```hcl
module "app_ecs_service" {
source = "../../modules/aws-ecs-service"
Expand All @@ -29,8 +54,8 @@ module "app_ecs_service" {
tasks_minimum_healthy_percent = 50
tasks_maximum_percent = 200
associate_lb = true
lb_security_group = "${module.security_group.id}"
associate_nlb = true
nlb_subnet_cidr_blocks = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
lb_target_group = "${module.target_group.id}"
}
```
Expand All @@ -40,7 +65,9 @@ module "app_ecs_service" {

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| associate_lb | Whether to associate a Load Balancer with the ECS service. | string | `false` | no |
| alb_security_group | Application Load Balancer (ALB) security group ID to allow traffic from. | string | `` | no |
| associate_alb | Whether to associate an Application Load Balancer (ALB) with the ECS service. | string | `false` | no |
| associate_nlb | Whether to associate a Network Load Balancer (NLB) with the ECS service. | string | `false` | no |
| container_definitions | Container definitions provided as valid JSON document. Default uses nginx:stable. | string | `` | no |
| container_port | The port on which the container will receive traffic. | string | `80` | no |
| ecs_cluster_arn | The ARN of the ECS cluster. | string | - | yes |
Expand All @@ -51,11 +78,11 @@ module "app_ecs_service" {
| environment | Environment tag, e.g prod. | string | - | yes |
| fargate_task_cpu | Number of cpu units used in initial task definition. Default is minimum. | string | `256` | no |
| fargate_task_memory | Amount (in MiB) of memory used in initiail task definition. Default is minimum. | string | `512` | no |
| lb_security_group | Load Balancer security group ID to allow traffic from. | string | `` | no |
| lb_target_group | Load Balancer target group ARN tasks will register with. | string | `` | no |
| lb_target_group | Either Application Load Balancer (ALB) or Network Load Balancer (NLB) target group ARN tasks will register with. | string | `` | no |
| logs_cloudwatch_group | CloudWatch log group to create and use. Default: /ecs/{name}-{environment} | string | `` | no |
| logs_cloudwatch_retention | Number of days you want to retain log events in the log group. | string | `90` | no |
| name | The service name. | string | - | yes |
| nlb_subnet_cidr_blocks | List of Network Load Balancer (NLB) CIDR blocks to allow traffic from. | list | `<list>` | no |
| tasks_desired_count | The number of instances of a task definition. | string | `1` | no |
| tasks_maximum_percent | Upper limit on the number of running tasks. | string | `200` | no |
| tasks_minimum_healthy_percent | Lower limit on the number of running tasks. | string | `100` | no |
Expand Down
50 changes: 44 additions & 6 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* * Security Groups for the ECS service.
* * ECS service.
* * Task definition using `nginx:stable` (see below).
* * Configurable associations with Network Load Balancers (NLB) and Application Load Balancers (ALB).
*
* We create an initial task definition using the `nginx:stable` image as a way
* to validate the initial infrastructure is working: visiting the site shows
Expand All @@ -15,6 +16,8 @@
*
* ## Usage
*
* ### ECS service associated with an Application Load Balancer (ALB)
*
* ```hcl
* module "app_ecs_service" {
* source = "../../modules/aws-ecs-service"
Expand All @@ -29,8 +32,30 @@
* tasks_minimum_healthy_percent = 50
* tasks_maximum_percent = 200
*
* associate_lb = true
* lb_security_group = "${module.security_group.id}"
* associate_alb = true
* alb_security_group = "${module.security_group.id}"
* lb_target_group = "${module.target_group.id}"
* }
* ```
*
* ### ECS Service associated with a Network Load Balancer(NLB)
*
* ```hcl
* module "app_ecs_service" {
* source = "../../modules/aws-ecs-service"
*
* name = "app"
* environment = "prod"
*
* ecs_cluster_arn = "${module.app_ecs_cluster.ecs_cluster_arn}"
* ecs_vpc_id = "${module.vpc.vpc_id}"
* ecs_subnet_ids = "${module.vpc.private_subnets}"
* tasks_desired_count = 2
* tasks_minimum_healthy_percent = 50
* tasks_maximum_percent = 200
*
* associate_nlb = true
* nlb_subnet_cidr_blocks = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
* lb_target_group = "${module.target_group.id}"
* }
* ```
Expand Down Expand Up @@ -113,7 +138,7 @@ resource "aws_security_group_rule" "app_ecs_allow_outbound" {
}

resource "aws_security_group_rule" "app_ecs_allow_https_from_alb" {
count = "${var.associate_lb}"
count = "${var.associate_alb}"

description = "Allow in ALB"
security_group_id = "${aws_security_group.ecs_sg.id}"
Expand All @@ -122,7 +147,20 @@ resource "aws_security_group_rule" "app_ecs_allow_https_from_alb" {
from_port = "${var.container_port}"
to_port = "${var.container_port}"
protocol = "tcp"
source_security_group_id = "${var.lb_security_group}"
source_security_group_id = "${var.alb_security_group}"
}

resource "aws_security_group_rule" "app_ecs_allow_tcp_from_nlb" {
count = "${var.associate_nlb}"

description = "Allow in NLB"
security_group_id = "${aws_security_group.ecs_sg.id}"

type = "ingress"
from_port = "${var.container_port}"
to_port = "${var.container_port}"
protocol = "tcp"
cidr_blocks = ["${var.nlb_subnet_cidr_blocks}"]
}

#
Expand Down Expand Up @@ -308,7 +346,7 @@ locals {
}

resource "aws_ecs_service" "main" {
count = "${var.associate_lb}"
count = "${var.associate_alb || var.associate_nlb ? 1 : 0}"

name = "${var.name}"
cluster = "${var.ecs_cluster_arn}"
Expand Down Expand Up @@ -348,7 +386,7 @@ resource "aws_ecs_service" "main" {
# the load_balancer argument due to this Terraform bug:
# https://github.com/hashicorp/terraform/issues/16856
resource "aws_ecs_service" "main_no_lb" {
count = "${var.associate_lb == 1 ? 0 : 1}"
count = "${var.associate_alb || var.associate_nlb ? 0 : 1}"

name = "${var.name}"
cluster = "${var.ecs_cluster_arn}"
Expand Down
43 changes: 36 additions & 7 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
variable "name" {
description = "The service name."
type = "string"
}

variable "environment" {
description = "Environment tag, e.g prod."
type = "string"
}

variable "logs_cloudwatch_retention" {
description = "Number of days you want to retain log events in the log group."
default = 90
type = "string"
}

variable "logs_cloudwatch_group" {
description = "CloudWatch log group to create and use. Default: /ecs/{name}-{environment}"
default = ""
type = "string"
}

variable "ecs_use_fargate" {
description = "Whether to use Fargate for the task definition."
default = false
type = "string"
}

variable "ecs_cluster_arn" {
description = "The ARN of the ECS cluster."
type = "string"
}

variable "ecs_instance_role" {
description = "The name of the ECS instance role."
type = "string"
default = ""
type = "string"
}

variable "ecs_vpc_id" {
description = "VPC ID to be used by ECS."
type = "string"
}

variable "ecs_subnet_ids" {
Expand All @@ -43,49 +50,71 @@ variable "ecs_subnet_ids" {
variable "fargate_task_cpu" {
description = "Number of cpu units used in initial task definition. Default is minimum."
default = 256
type = "string"
}

variable "fargate_task_memory" {
description = "Amount (in MiB) of memory used in initiail task definition. Default is minimum."
default = 512
type = "string"
}

variable "tasks_desired_count" {
description = "The number of instances of a task definition."
default = 1
type = "string"
}

variable "tasks_minimum_healthy_percent" {
description = "Lower limit on the number of running tasks."
default = "100"
type = "string"
}

variable "tasks_maximum_percent" {
description = "Upper limit on the number of running tasks."
default = "200"
type = "string"
}

variable "container_port" {
description = "The port on which the container will receive traffic."
default = 80
type = "string"
}

variable "container_definitions" {
description = "Container definitions provided as valid JSON document. Default uses nginx:stable."
default = ""
type = "string"
}

variable "associate_lb" {
description = "Whether to associate a Load Balancer with the ECS service."
variable "associate_alb" {
description = "Whether to associate an Application Load Balancer (ALB) with the ECS service."
default = false
type = "string"
}

variable lb_security_group {
description = "Load Balancer security group ID to allow traffic from."
variable "associate_nlb" {
description = "Whether to associate a Network Load Balancer (NLB) with the ECS service."
default = false
type = "string"
}

variable "alb_security_group" {
description = "Application Load Balancer (ALB) security group ID to allow traffic from."
default = ""
type = "string"
}

variable lb_target_group {
description = "Load Balancer target group ARN tasks will register with."
variable "lb_target_group" {
description = "Either Application Load Balancer (ALB) or Network Load Balancer (NLB) target group ARN tasks will register with."
default = ""
type = "string"
}

variable "nlb_subnet_cidr_blocks" {
description = "List of Network Load Balancer (NLB) CIDR blocks to allow traffic from."
default = []
type = "list"
}

0 comments on commit 1e491e1

Please sign in to comment.