Skip to content

Adding EC2 capacity in ECS Module #71

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ module "ecs_cluster" {
use_fargate = var.capacity_provider.use_fargate
fargate_capacity_providers = var.capacity_provider.fargate_capacity_providers
}

launch_template = {
name = "lt1"
}

asg = {
max_size = 2
min_size = 1
}
}


Expand Down
129 changes: 127 additions & 2 deletions modules/ecs_cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,142 @@ resource "aws_ecs_cluster" "this" {
tags = merge(var.tags, var.ecs_cluster.tags)
}

################################################################################
# EC2 Launch Template
################################################################################

resource "aws_launch_template" "this" {
count = var.capacity_provider.use_fargate != true ? 1 : 0

name = var.launch_template.name

dynamic "block_device_mappings" {
for_each = var.launch_template.block_device_mappings
content {
device_name = block_device_mappings.value.device_name

dynamic "ebs" {
for_each = block_device_mappings.value.ebs != null ? [block_device_mappings.value.ebs] : []
content {
volume_size = ebs.value.volume_size
}
}
}
}

dynamic "cpu_options" {
for_each = var.launch_template.cpu_options != null ? [var.launch_template.cpu_options] : []
content {
core_count = cpu_options.value.core_count
threads_per_core = cpu_options.value.threads_per_core
}
}

disable_api_stop = var.launch_template.disable_api_stop
disable_api_termination = var.launch_template.disable_api_termination
ebs_optimized = var.launch_template.ebs_optimized

dynamic "elastic_gpu_specifications" {
for_each = var.launch_template.elastic_gpu_specifications
content {
type = elastic_gpu_specifications.value.type
}
}

dynamic "iam_instance_profile" {
for_each = var.launch_template.iam_instance_profile != null ? [var.launch_template.iam_instance_profile] : []
content {
name = iam_instance_profile.value.name
}
}

image_id = var.launch_template.image_id

instance_initiated_shutdown_behavior = var.launch_template.instance_initiated_shutdown_behavior

dynamic "monitoring" {
for_each = var.launch_template.monitoring != null ? [var.launch_template.monitoring] : []
content {
enabled = monitoring.value.enabled
}
}

dynamic "network_interfaces" {
for_each = var.launch_template.network_interfaces
content {
associate_public_ip_address = network_interfaces.value.associate_public_ip_address
ipv4_prefixes = network_interfaces.value.ipv4_prefixes
ipv6_prefixes = network_interfaces.value.ipv6_prefixes
ipv4_addresses = network_interfaces.value.ipv4_addresses
ipv6_addresses = network_interfaces.value.ipv6_addresses
network_interface_id = network_interfaces.value.network_interface_id
private_ip_address = network_interfaces.value.private_ip_address
security_groups = network_interfaces.value.security_groups
subnet_id = network_interfaces.value.subnet_id
}
}

dynamic "placement" {
for_each = var.launch_template.placement != null ? [var.launch_template.placement] : []
content {
availability_zone = placement.value.availability_zone
}
}

vpc_security_group_ids = var.launch_template.vpc_security_group_ids

dynamic "tag_specifications" {
for_each = var.launch_template.tag_specifications
content {
resource_type = tag_specifications.value.resource_type
tags = tag_specifications.value.tags
}
}

user_data = var.launch_template.user_data != null ? filebase64(var.launch_template.user_data) : null
}

################################################################################
# Auto Scaling Group
################################################################################

resource "aws_autoscaling_group" "this" {
count = var.capacity_provider.use_fargate != true ? 1 : 0

name = var.asg.name != null ? var.asg.name : "ecs-auto-scaling-group"
min_size = var.asg.min_size
max_size = var.asg.max_size
desired_capacity = var.asg.desired_capacity != null ? var.asg.desired_capacity : var.asg.min_size
vpc_zone_identifier = var.asg.vpc_zone_identifier != null ? var.asg.vpc_zone_identifier : []

launch_template {
id = aws_launch_template.this[0].id
}

health_check_type = var.asg.health_check_type != null ? var.asg.health_check_type : "EC2"
health_check_grace_period = var.asg.health_check_grace_period != null ? var.asg.health_check_grace_period : 300
protect_from_scale_in = var.asg.protect_from_scale_in != null ? var.asg.protect_from_scale_in : false
default_cooldown = var.asg.default_cooldown != null ? var.asg.default_cooldown : 300

instance_refresh {
strategy = var.asg.instance_refresh.strategy
preferences {
min_healthy_percentage = var.asg.instance_refresh.preferences != null && var.asg.instance_refresh.preferences.min_healthy_percentage != null ? var.asg.instance_refresh.preferences.min_healthy_percentage : 50
}
}
}

################################################################################
# ECS Capacity Provider - EC2
################################################################################

resource "aws_ecs_capacity_provider" "this" {
for_each = var.capacity_provider.autoscaling_capacity_providers != null ? var.capacity_provider.autoscaling_capacity_providers : {}
for_each = (var.capacity_provider.use_fargate != true && var.capacity_provider.autoscaling_capacity_providers != null) ? var.capacity_provider.autoscaling_capacity_providers : {}

name = each.value.name != "" ? each.value.name : each.key

auto_scaling_group_provider {
auto_scaling_group_arn = each.value.auto_scaling_group_arn
auto_scaling_group_arn = aws_autoscaling_group.this[0].arn

# Enable managed termination protection only if managed scaling is defined
managed_termination_protection = each.value.managed_scaling != null ? (each.value.managed_termination_protection != null ? each.value.managed_termination_protection : "DISABLED") : "DISABLED"
Expand Down
86 changes: 86 additions & 0 deletions modules/ecs_cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,93 @@ EOT
}
}

variable "launch_template" {
type = object({
name = string
block_device_mappings = optional(list(object({
device_name = string
ebs = optional(object({
volume_size = number
}))
})), [])

cpu_options = optional(object({
core_count = number
threads_per_core = number
}), null)

disable_api_stop = optional(bool, false)
disable_api_termination = optional(bool, false)
ebs_optimized = optional(bool, false)

elastic_gpu_specifications = optional(list(object({
type = string
})), [])

iam_instance_profile = optional(object({
name = string
}), null)

image_id = optional(string, null)
instance_initiated_shutdown_behavior = optional(string, "stop")

instance_type = optional(string, null)
kernel_id = optional(string, null)
key_name = optional(string, null)

monitoring = optional(object({
enabled = bool
}), null)

network_interfaces = optional(list(object({
associate_public_ip_address = optional(bool, null)
ipv4_prefixes = optional(list(string), [])
ipv6_prefixes = optional(list(string), [])
ipv4_addresses = optional(list(string), [])
ipv6_addresses = optional(list(string), [])
network_interface_id = optional(string, null)
private_ip_address = optional(string, null)
security_groups = optional(list(string), [])
subnet_id = optional(string, null)
})), [])

placement = optional(object({
availability_zone = string
}), null)

vpc_security_group_ids = optional(list(string), [])

tag_specifications = optional(list(object({
resource_type = string
tags = map(string)
})), [])

user_data = optional(string, null)
})
}

variable "asg" {
description = "Auto Scaling Group configuration"
type = object({
name = optional(string, null)
min_size = number
max_size = number
desired_capacity = optional(number)
vpc_zone_identifier = optional(list(string))

health_check_type = optional(string)
health_check_grace_period = optional(number, 300)
protect_from_scale_in = optional(bool)
default_cooldown = optional(number)

instance_refresh = optional(object({
strategy = string
preferences = optional(object({
min_healthy_percentage = optional(number)
}))
}))
})
}

################################################################################
# Cluster Capacity Providers
Expand Down
89 changes: 89 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,95 @@ variable "capacity_provider" {
}


/* variable "launch_template" {
type = object({
name = string
block_device_mappings = optional(list(object({
device_name = string
ebs = optional(object({
volume_size = number
}))
})), [])

cpu_options = optional(object({
core_count = number
threads_per_core = number
}), null)

disable_api_stop = optional(bool, false)
disable_api_termination = optional(bool, false)
ebs_optimized = optional(bool, false)

elastic_gpu_specifications = optional(list(object({
type = string
})), [])

iam_instance_profile = optional(object({
name = string
}), null)

image_id = optional(string, null)
instance_initiated_shutdown_behavior = optional(string, "stop")

instance_type = optional(string, null)
kernel_id = optional(string, null)
key_name = optional(string, null)

monitoring = optional(object({
enabled = bool
}), null)

network_interfaces = optional(list(object({
associate_public_ip_address = optional(bool, null)
ipv4_prefixes = optional(list(string), [])
ipv6_prefixes = optional(list(string), [])
ipv4_addresses = optional(list(string), [])
ipv6_addresses = optional(list(string), [])
network_interface_id = optional(string, null)
private_ip_address = optional(string, null)
security_groups = optional(list(string), [])
subnet_id = optional(string, null)
})), [])

placement = optional(object({
availability_zone = string
}), null)

vpc_security_group_ids = optional(list(string), [])

tag_specifications = optional(list(object({
resource_type = string
tags = map(string)
})), [])

user_data = optional(string, null)
})
}

variable "asg" {
description = "Auto Scaling Group configuration"
type = object({
name = optional(string, null)
min_size = number
max_size = number
desired_capacity = optional(number)
vpc_zone_identifier = optional(list(string))

health_check_type = optional(string)
health_check_grace_period = optional(number, 300)
protect_from_scale_in = optional(bool)
default_cooldown = optional(number)

instance_refresh = object({
strategy = string
preferences = optional(object({
min_healthy_percentage = optional(number)
}))
})
})
} */


################################################################################
## ALB
################################################################################
Expand Down
Loading