Last active
July 18, 2023 21:03
-
-
Save alexjeen/984dd2b092ffa49e1c3bf4f6505d0ebe to your computer and use it in GitHub Desktop.
Autoscaling ECS cluster (Terraform)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
variable "prefix" { | |
type = string | |
} | |
variable "vpc_id" { | |
type = string | |
} | |
variable "private_subnets" { | |
type = list(string) | |
default = [] | |
} | |
locals { | |
sizes = ["xxl", "xxxl"] | |
sizeMap = { | |
xxl = "m6a.4xlarge" | |
xxxl = "m6a.8xlarge" | |
} | |
} | |
// execution role for the ec2 instances | |
resource "aws_iam_role" "execution_role" { | |
name = "${var.prefix}-ecs-ec2-role" | |
assume_role_policy = jsonencode({ | |
Version = "2012-10-17" | |
Statement = [ | |
{ | |
Action = "sts:AssumeRole" | |
Effect = "Allow" | |
Sid = "" | |
Principal = { | |
Service = "ec2.amazonaws.com" | |
} | |
} | |
] | |
}) | |
} | |
// attach the general permissions to for instance | |
resource "aws_iam_role_policy_attachment" "ecs_task_permissions" { | |
role = aws_iam_role.execution_role.name | |
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" | |
} | |
// ecs optimized ami | |
data "aws_ssm_parameter" "ami" { | |
name = "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id" | |
} | |
// create the security group | |
module "security_group" { | |
source = "terraform-aws-modules/security-group/aws" | |
name = "${var.prefix}-ec2-ecs-security-group" | |
vpc_id = var.vpc_id | |
ingress_with_source_security_group_id = [] | |
egress_rules = ["all-all"] | |
} | |
resource "aws_iam_instance_profile" "instance_profile" { | |
name = "${var.prefix}-instanceprofile" | |
role = aws_iam_role.execution_role.name | |
} | |
resource "aws_launch_template" "launchtemplate" { | |
for_each = toset(local.sizes) | |
name = "${var.prefix}-template-${each.value}" | |
block_device_mappings { | |
device_name = "/dev/sda1" | |
ebs { | |
volume_size = 60 | |
encrypted = true | |
delete_on_termination = true | |
} | |
} | |
update_default_version = true | |
iam_instance_profile { | |
arn = aws_iam_instance_profile.instance_profile.arn | |
} | |
image_id = data.aws_ssm_parameter.ami.value | |
instance_type = local.sizeMap[each.value] | |
monitoring { | |
enabled = true | |
} | |
vpc_security_group_ids = [ | |
module.security_group.security_group_id | |
] | |
user_data = base64encode( | |
<<EOF | |
#!/bin/bash | |
echo "ECS_CLUSTER=${var.prefix}-cluster" >> /etc/ecs/ecs.config | |
EOF | |
) | |
} | |
resource "aws_autoscaling_group" "asg" { | |
lifecycle { | |
ignore_changes = [ | |
tags | |
] | |
} | |
for_each = toset(local.sizes) | |
name = "${var.prefix}-asg-${each.value}" | |
desired_capacity = 0 | |
max_size = 1 | |
min_size = 0 | |
protect_from_scale_in = true | |
vpc_zone_identifier = var.private_subnets | |
launch_template { | |
id = aws_launch_template.launchtemplate[each.value].id | |
version = "$Latest" | |
} | |
} | |
resource "aws_ecs_capacity_provider" "cp" { | |
for_each = toset(local.sizes) | |
name = upper(each.value) | |
auto_scaling_group_provider { | |
auto_scaling_group_arn = aws_autoscaling_group.asg[each.value].arn | |
managed_termination_protection = "ENABLED" | |
managed_scaling { | |
status = "ENABLED" | |
target_capacity = 100 | |
} | |
} | |
} | |
// the cluster to run stuff in | |
resource "aws_ecs_cluster" "ecs" { | |
depends_on = [ | |
aws_ecs_capacity_provider.cp | |
] | |
name = "${var.prefix}-cluster" | |
capacity_providers = ["FARGATE", "FARGATE_SPOT", "XXL", "XXXL"] | |
default_capacity_provider_strategy { | |
capacity_provider = "FARGATE" | |
} | |
setting { | |
name = "containerInsights" | |
value = "enabled" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ecs.runTask({ | |
// further parameters for runtask | |
launchType: null, | |
capacityProviderStrategy = [ | |
{ | |
// to run the task on the XXL cluster | |
"capacityProvider": "XXL" | |
} | |
] | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment