Skip to content

Commit

Permalink
Create separate service definitions for auto-scaling, and static (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
dipack95 authored Feb 8, 2022
1 parent 905c2ac commit 0e459d9
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 59 deletions.
167 changes: 110 additions & 57 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,15 +1,72 @@
locals {
security_group_id = length(var.security_group_id) > 0 ? var.security_group_id : aws_security_group.service_security_group[0].id
role_arn = length(var.execution_role_arn) > 0 ? var.execution_role_arn : aws_iam_role.execution_role[0].arn
}

data "aws_ecs_cluster" "cluster" {
arn = var.cluster_id
resource "aws_ecs_task_definition" "task" {
family = "${var.name}-task"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = var.cpu
memory = var.memory
execution_role_arn = local.role_arn
task_role_arn = local.role_arn
container_definitions = var.container_definitions
tags = var.tags

dynamic "volume" {
for_each = var.volumes

content {
name = volume.value["name"]
host_path = lookup(volume.value, "host_path", null)
}
}

ephemeral_storage {
size_in_gib = var.ephemeral_storage_gib
}
}

resource "aws_security_group" "service_security_group" {
count = length(var.security_group_id) == 0 ? 1 : 0
name = "${var.name}-ecs-security-group"
description = "Allows inbound access to an ECS service only through its alb"
vpc_id = var.vpc_id

dynamic "ingress" {
for_each = var.load_balancers
content {
from_port = ingress.value.container_port
to_port = ingress.value.container_port
security_groups = var.alb_security_group_ids
protocol = "tcp"
}
}

# Allow all outgoing access
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

timeouts {
create = "45m"
delete = "45m"
}

tags = var.tags
}

resource "aws_ecs_service" "service" {
# Service, with no Auto-scaling configured.
resource "aws_ecs_service" "service_no_autoscaling" {
count = var.use_autoscaling ? 0 : 1

name = var.name
cluster = var.cluster_id
desired_count = var.use_autoscaling ? null : var.desired_count
desired_count = var.desired_count

task_definition = aws_ecs_task_definition.task.arn
launch_type = "FARGATE"
Expand Down Expand Up @@ -54,91 +111,87 @@ resource "aws_ecs_service" "service" {
}
}

lifecycle {
ignore_changes = concat([], var.use_autoscaling ? [desired_count] : [])
}

propagate_tags = "SERVICE"
tags = var.tags
}

locals {
role_arn = length(var.execution_role_arn) > 0 ? var.execution_role_arn : aws_iam_role.execution_role[0].arn
}

resource "aws_ecs_task_definition" "task" {
family = "${var.name}-task"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = var.cpu
memory = var.memory
execution_role_arn = local.role_arn
task_role_arn = local.role_arn
container_definitions = var.container_definitions
tags = var.tags
# Service wth Auto-scaling configured.
resource "aws_ecs_service" "service_autoscaling" {
count = var.use_autoscaling ? 1 : 0

dynamic "volume" {
for_each = var.volumes
name = var.name
cluster = var.cluster_id
desired_count = var.min_desired_count

content {
name = volume.value["name"]
host_path = lookup(volume.value, "host_path", null)
}
task_definition = aws_ecs_task_definition.task.arn
launch_type = "FARGATE"

network_configuration {
security_groups = [local.security_group_id]
subnets = var.subnet_ids
assign_public_ip = false
}

ephemeral_storage {
size_in_gib = var.ephemeral_storage_gib
deployment_controller {
type = "ECS"
}
}

resource "aws_security_group" "service_security_group" {
count = length(var.security_group_id) == 0 ? 1 : 0
name = "${var.name}-ecs-security-group"
description = "Allows inbound access to an ECS service only through its alb"
vpc_id = var.vpc_id
health_check_grace_period_seconds = var.health_check_grace_period_seconds

dynamic "ingress" {
dynamic "capacity_provider_strategy" {
for_each = var.capacity_provider_strategies
content {
base = capacity_provider_strategy.value.base
capacity_provider = capacity_provider_strategy.value.capacity_provider
weight = capacity_provider_strategy.value.weight
}
}

dynamic "load_balancer" {
for_each = var.load_balancers
content {
from_port = ingress.value.container_port
to_port = ingress.value.container_port
security_groups = var.alb_security_group_ids
protocol = "tcp"
target_group_arn = load_balancer.value.target_group_arn
container_name = load_balancer.value.container_name
container_port = load_balancer.value.container_port
}
}

# Allow all outgoing access
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
dynamic "service_registries" {
for_each = var.service_registries
content {
registry_arn = service_registries.value.registry_arn
container_name = lookup(service_registries.value, "container_name", null)
container_port = lookup(service_registries.value, "container_port", null)
port = lookup(service_registries.value, "port", null)
}
}

timeouts {
create = "45m"
delete = "45m"
lifecycle {
ignore_changes = [desired_count]
}

tags = var.tags
propagate_tags = "SERVICE"
tags = var.tags
}


resource "aws_appautoscaling_target" "ecs_service_autoscaling_target" {
for_each = var.use_autoscaling ? [1] : []
count = var.use_autoscaling ? 1 : 0

min_capacity = var.min_desired_count
max_capacity = var.max_desired_count
scalable_dimension = "ecs:service:DesiredCount"
service_namespace = "ecs"
resource_id = "service/${data.aws_ecs_cluster.cluster.cluster_name}/${aws_ecs_service.service.name}"
resource_id = "service/${var.cluster_name}/${aws_ecs_service.service_autoscaling[0].name}"
}

resource "aws_appautoscaling_policy" "ecs_service_autoscaling_policy" {
count = var.use_autoscaling ? 1 : 0

name = "ecs-fargate-service-autoscaling-policy"
service_namespace = aws_appautoscaling_target.ecs_service_autoscaling_target.service_namespace
scalable_dimension = aws_appautoscaling_target.ecs_service_autoscaling_target.scalable_dimension
resource_id = aws_appautoscaling_target.ecs_service_autoscaling_target.resource_id
service_namespace = aws_appautoscaling_target.ecs_service_autoscaling_target[0].service_namespace
scalable_dimension = aws_appautoscaling_target.ecs_service_autoscaling_target[0].scalable_dimension
resource_id = aws_appautoscaling_target.ecs_service_autoscaling_target[0].resource_id
policy_type = "TargetTrackingScaling"

target_tracking_scaling_policy_configuration {
Expand All @@ -151,4 +204,4 @@ resource "aws_appautoscaling_policy" "ecs_service_autoscaling_policy" {
predefined_metric_type = var.scaling_metric
}
}
}
}
9 changes: 7 additions & 2 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ variable "cluster_id" {
EOF
}

variable "cluster_name" {
type = string
description = "The name of the ECS cluster this service will run in."
}

variable "desired_count" {
type = number
description = "If not using Application Auto-scaling, the number of tasks to keep alive at all times"
Expand Down Expand Up @@ -170,7 +175,7 @@ variable "capacity_provider_strategies" {
}

variable "ephemeral_storage_gib" {
description = "The total amount, in GiB, of ephemeral storage to set for the task. The minimum supported value is 20 GiB and the maximum supported value is 200 GiB."
description = "The total amount, in GiB, of ephemeral storage to set for the task. The minimum supported value is 21 GiB and the maximum supported value is 200 GiB."
type = number
default = 20
default = 21
}

0 comments on commit 0e459d9

Please sign in to comment.