301 lines
6.9 KiB
HCL
301 lines
6.9 KiB
HCL
################################################################################
|
|
# Cluster
|
|
################################################################################
|
|
|
|
module "ecs_cluster" {
|
|
source = "./modules/cluster"
|
|
|
|
cluster_name = local.name
|
|
|
|
# Capacity provider
|
|
fargate_capacity_providers = {
|
|
FARGATE = {
|
|
default_capacity_provider_strategy = {
|
|
weight = 50
|
|
base = 20
|
|
}
|
|
}
|
|
FARGATE_SPOT = {
|
|
default_capacity_provider_strategy = {
|
|
weight = 50
|
|
}
|
|
}
|
|
}
|
|
|
|
tags = local.tags
|
|
}
|
|
|
|
################################################################################
|
|
# Service
|
|
################################################################################
|
|
|
|
module "ecs_service" {
|
|
source = "./modules/service"
|
|
|
|
name = local.name
|
|
cluster_arn = module.ecs_cluster.arn
|
|
desired_count = 1
|
|
cpu = 1024
|
|
memory = 4096
|
|
|
|
# Enables ECS Exec
|
|
enable_execute_command = true
|
|
|
|
# Container definition(s)
|
|
container_definitions = {
|
|
|
|
(local.container_name) = {
|
|
cpu = 512
|
|
memory = 1024
|
|
image = "richarvey/chat-app:latest"
|
|
port_mappings = [
|
|
{
|
|
name = local.container_name
|
|
containerPort = local.container_port
|
|
hostPort = local.container_port
|
|
protocol = "tcp"
|
|
}
|
|
]
|
|
|
|
environment = [
|
|
{
|
|
name = "REDIS_ENDPOINT"
|
|
value = "valkey"
|
|
},
|
|
]
|
|
|
|
memory_reservation = 100
|
|
}
|
|
}
|
|
|
|
service_connect_configuration = {
|
|
namespace = aws_service_discovery_http_namespace.this.arn
|
|
service = {
|
|
client_alias = {
|
|
port = local.container_port
|
|
dns_name = local.container_name
|
|
}
|
|
port_name = local.container_name
|
|
discovery_name = local.container_name
|
|
}
|
|
}
|
|
|
|
load_balancer = {
|
|
service = {
|
|
target_group_arn = module.alb.target_groups["ex_ecs"].arn
|
|
container_name = local.container_name
|
|
container_port = local.container_port
|
|
}
|
|
}
|
|
|
|
subnet_ids = module.vpc.private_subnets
|
|
security_group_rules = {
|
|
alb_ingress_3000 = {
|
|
type = "ingress"
|
|
from_port = local.container_port
|
|
to_port = local.container_port
|
|
protocol = "tcp"
|
|
description = "Service port"
|
|
source_security_group_id = module.alb.security_group_id
|
|
}
|
|
egress_all = {
|
|
type = "egress"
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
}
|
|
|
|
service_tags = {
|
|
"ServiceTag" = "Tag on service level"
|
|
}
|
|
|
|
tags = local.tags
|
|
}
|
|
|
|
resource "aws_ecs_task_definition" "task" {
|
|
family = "service"
|
|
network_mode = "awsvpc"
|
|
requires_compatibilities = ["FARGATE", "EC2"]
|
|
cpu = 512
|
|
memory = 1024
|
|
container_definitions = jsonencode([
|
|
{
|
|
name = "valkey"
|
|
image = "valkey/valkey:7.2.4-rc1-alpine"
|
|
cpu = 512
|
|
memory = 1024
|
|
essential = true # if true and if fails, all other containers fail. Must have at least one essential
|
|
portMappings = [
|
|
{
|
|
name = "valkey"
|
|
containerPort = 6379
|
|
hostPort = 6379
|
|
}
|
|
]
|
|
}
|
|
])
|
|
}
|
|
|
|
resource "aws_ecs_service" "service" {
|
|
name = "valkey"
|
|
cluster = module.ecs_cluster.id
|
|
task_definition = aws_ecs_task_definition.task.id
|
|
desired_count = 1
|
|
launch_type = "FARGATE"
|
|
platform_version = "LATEST"
|
|
|
|
network_configuration {
|
|
assign_public_ip = false
|
|
security_groups = [aws_security_group.sg.id]
|
|
subnets = module.vpc.private_subnets
|
|
}
|
|
lifecycle {
|
|
ignore_changes = [task_definition]
|
|
}
|
|
|
|
service_connect_configuration {
|
|
enabled = true
|
|
namespace = "chat-app-demo"
|
|
service {
|
|
discovery_name = "valkey"
|
|
port_name = "valkey"
|
|
client_alias {
|
|
dns_name = "valkey"
|
|
port = 6379
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
resource "aws_security_group" "sg" {
|
|
name = "ecs"
|
|
vpc_id = module.vpc.vpc_id
|
|
|
|
egress {
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
ingress {
|
|
protocol = -1
|
|
self = true
|
|
from_port = 0
|
|
to_port = 0
|
|
description = ""
|
|
}
|
|
|
|
ingress {
|
|
from_port = 6379
|
|
to_port = 6379
|
|
protocol = "tcp"
|
|
self = "false"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
description = "Port 80"
|
|
}
|
|
|
|
}
|
|
|
|
resource "null_resource" "update_desired_count" {
|
|
triggers = {
|
|
# Changes to this value will trigger the API call execution below
|
|
desired_count = 3
|
|
}
|
|
|
|
provisioner "local-exec" {
|
|
interpreter = ["/bin/bash", "-c"]
|
|
|
|
# Note: this requires the awscli to be installed locally where Terraform is executed
|
|
command = <<-EOT
|
|
aws ecs update-service \
|
|
--cluster ${module.ecs_cluster.name} \
|
|
--service ${module.ecs_service.name} \
|
|
--desired-count ${null_resource.update_desired_count.triggers.desired_count}
|
|
EOT
|
|
}
|
|
}
|
|
|
|
################################################################################
|
|
# Supporting Resources
|
|
################################################################################
|
|
|
|
resource "aws_service_discovery_http_namespace" "this" {
|
|
name = local.name
|
|
description = "CloudMap namespace for ${local.name}"
|
|
tags = local.tags
|
|
}
|
|
|
|
module "alb" {
|
|
source = "terraform-aws-modules/alb/aws"
|
|
version = "~> 9.0"
|
|
|
|
name = local.name
|
|
|
|
load_balancer_type = "application"
|
|
|
|
vpc_id = module.vpc.vpc_id
|
|
subnets = module.vpc.public_subnets
|
|
|
|
# For example only
|
|
enable_deletion_protection = false
|
|
|
|
# Security Group
|
|
security_group_ingress_rules = {
|
|
all_http = {
|
|
from_port = 80
|
|
to_port = 80
|
|
ip_protocol = "tcp"
|
|
cidr_ipv4 = "0.0.0.0/0"
|
|
}
|
|
}
|
|
security_group_egress_rules = {
|
|
all = {
|
|
ip_protocol = "-1"
|
|
cidr_ipv4 = module.vpc.vpc_cidr_block
|
|
}
|
|
}
|
|
|
|
listeners = {
|
|
ex_http = {
|
|
port = 80
|
|
protocol = "HTTP"
|
|
|
|
forward = {
|
|
target_group_key = "ex_ecs"
|
|
}
|
|
}
|
|
}
|
|
|
|
target_groups = {
|
|
ex_ecs = {
|
|
backend_protocol = "HTTP"
|
|
backend_port = local.container_port
|
|
target_type = "ip"
|
|
deregistration_delay = 5
|
|
load_balancing_cross_zone_enabled = true
|
|
|
|
health_check = {
|
|
enabled = true
|
|
healthy_threshold = 5
|
|
interval = 30
|
|
matcher = "200"
|
|
path = "/"
|
|
port = "traffic-port"
|
|
protocol = "HTTP"
|
|
timeout = 5
|
|
unhealthy_threshold = 2
|
|
}
|
|
|
|
# There's nothing to attach here in this definition. Instead,
|
|
# ECS will attach the IPs of the tasks to this target group
|
|
create_attachment = false
|
|
}
|
|
}
|
|
|
|
tags = local.tags
|
|
}
|