diff --git a/services/terraform/remote/alarms_backup.tf b/services/terraform/remote/alarms_backup.tf --- a/services/terraform/remote/alarms_backup.tf +++ b/services/terraform/remote/alarms_backup.tf @@ -59,7 +59,7 @@ alarm_description = "Alarm when Backup service memory utilization exceeds 90%" dimensions = { ClusterName = aws_ecs_cluster.comm_services.name - ServiceName = local.is_staging ? aws_ecs_service.backup_service_fargate[0].name : aws_ecs_service.backup_service.name + ServiceName = local.is_staging ? aws_ecs_service.backup_service_fargate.name : aws_ecs_service.backup_service.name } alarm_actions = [aws_sns_topic.backup_error_topic.arn] } @@ -76,7 +76,7 @@ alarm_description = "Alarm when Backup service CPU utilization exceeds 90%" dimensions = { ClusterName = aws_ecs_cluster.comm_services.name - ServiceName = local.is_staging ? aws_ecs_service.backup_service_fargate[0].name : aws_ecs_service.backup_service.name + ServiceName = local.is_staging ? aws_ecs_service.backup_service_fargate.name : aws_ecs_service.backup_service.name } alarm_actions = [aws_sns_topic.backup_error_topic.arn] } diff --git a/services/terraform/remote/alarms_blob.tf b/services/terraform/remote/alarms_blob.tf --- a/services/terraform/remote/alarms_blob.tf +++ b/services/terraform/remote/alarms_blob.tf @@ -59,7 +59,7 @@ alarm_description = "Alarm when Blob service memory utilization exceeds 90%" dimensions = { ClusterName = aws_ecs_cluster.comm_services.name - ServiceName = local.is_staging ? aws_ecs_service.blob_service_fargate[0].name : aws_ecs_service.blob_service.name + ServiceName = local.is_staging ? aws_ecs_service.blob_service_fargate.name : aws_ecs_service.blob_service.name } alarm_actions = [aws_sns_topic.blob_error_topic.arn] } @@ -76,7 +76,7 @@ alarm_description = "Alarm when Blob service CPU utilization exceeds 90%" dimensions = { ClusterName = aws_ecs_cluster.comm_services.name - ServiceName = local.is_staging ? aws_ecs_service.blob_service_fargate[0].name : aws_ecs_service.blob_service.name + ServiceName = local.is_staging ? aws_ecs_service.blob_service_fargate.name : aws_ecs_service.blob_service.name } alarm_actions = [aws_sns_topic.blob_error_topic.arn] } diff --git a/services/terraform/remote/alarms_tunnelbroker.tf b/services/terraform/remote/alarms_tunnelbroker.tf --- a/services/terraform/remote/alarms_tunnelbroker.tf +++ b/services/terraform/remote/alarms_tunnelbroker.tf @@ -65,7 +65,7 @@ namespace = "AWS/ECS" dimensions = { ClusterName = aws_ecs_cluster.comm_services.name - ServiceName = local.is_staging ? aws_ecs_service.tunnelbroker_fargate[0].name : aws_ecs_service.tunnelbroker.name + ServiceName = local.is_staging ? aws_ecs_service.tunnelbroker_fargate.name : aws_ecs_service.tunnelbroker.name } } @@ -83,6 +83,6 @@ namespace = "AWS/ECS" dimensions = { ClusterName = aws_ecs_cluster.comm_services.name - ServiceName = local.is_staging ? aws_ecs_service.tunnelbroker_fargate[0].name : aws_ecs_service.tunnelbroker.name + ServiceName = local.is_staging ? aws_ecs_service.tunnelbroker_fargate.name : aws_ecs_service.tunnelbroker.name } } diff --git a/services/terraform/remote/service_backup.tf b/services/terraform/remote/service_backup.tf --- a/services/terraform/remote/service_backup.tf +++ b/services/terraform/remote/service_backup.tf @@ -187,27 +187,21 @@ default_action { type = "forward" - # Production: Simple forwarding (unchanged) - target_group_arn = local.is_staging ? null : aws_lb_target_group.backup_service_http.arn - - # Staging: Weighted forwarding - dynamic "forward" { - for_each = local.is_staging ? [1] : [] - content { - target_group { - arn = aws_lb_target_group.backup_service_http.arn - weight = 0 # 0% EC2 - } + # Weighted forwarding for both environments + forward { + target_group { + arn = aws_lb_target_group.backup_service_http.arn + weight = local.is_staging ? 0 : 100 # Staging: 0% EC2, Prod: 100% EC2 + } - target_group { - arn = aws_lb_target_group.backup_service_http_fargate[0].arn - weight = 100 # 100% Fargate - } + target_group { + arn = aws_lb_target_group.backup_service_http_fargate.arn + weight = local.is_staging ? 100 : 0 # Staging: 100% Fargate, Prod: 0% Fargate + } - stickiness { - enabled = false - duration = 10 - } + stickiness { + enabled = false + duration = 10 } } } diff --git a/services/terraform/remote/service_backup_fargate.tf b/services/terraform/remote/service_backup_fargate.tf --- a/services/terraform/remote/service_backup_fargate.tf +++ b/services/terraform/remote/service_backup_fargate.tf @@ -1,6 +1,5 @@ -# Fargate task definition (staging only) +# Fargate task definition resource "aws_ecs_task_definition" "backup_service_fargate" { - count = local.is_staging ? 1 : 0 family = "backup-service-fargate-task-def" container_definitions = jsonencode([ { @@ -47,21 +46,20 @@ task_role_arn = aws_iam_role.backup_service.arn execution_role_arn = aws_iam_role.ecs_task_execution.arn network_mode = "awsvpc" - cpu = "256" - memory = "512" + cpu = local.is_staging ? "256" : "1024" + memory = local.is_staging ? "512" : "2048" requires_compatibilities = ["FARGATE"] skip_destroy = true } -# Fargate ECS Service (staging only) +# Fargate ECS Service resource "aws_ecs_service" "backup_service_fargate" { - count = local.is_staging ? 1 : 0 name = "backup-service-fargate" cluster = aws_ecs_cluster.comm_services.id launch_type = "FARGATE" - task_definition = aws_ecs_task_definition.backup_service_fargate[0].arn + task_definition = aws_ecs_task_definition.backup_service_fargate.arn force_new_deployment = true network_configuration { @@ -88,7 +86,7 @@ # HTTP load_balancer { - target_group_arn = aws_lb_target_group.backup_service_http_fargate[0].arn + target_group_arn = aws_lb_target_group.backup_service_http_fargate.arn container_name = local.backup_service_container_name container_port = local.backup_service_container_http_port } @@ -106,9 +104,8 @@ enable_ecs_managed_tags = true } -# Fargate HTTP target group (staging only) +# Fargate HTTP target group resource "aws_lb_target_group" "backup_service_http_fargate" { - count = local.is_staging ? 1 : 0 name = "backup-service-http-fargate-tg" port = local.backup_service_container_http_port protocol = "HTTP" @@ -126,12 +123,12 @@ } } -# Auto-scaling for Fargate service (staging only) +# Auto-scaling for Fargate service module "backup_service_fargate_autoscaling" { source = "../modules/fargate-autoscaling" - create_resources = local.is_staging - service_name = local.is_staging ? aws_ecs_service.backup_service_fargate[0].name : "" + create_resources = true + service_name = aws_ecs_service.backup_service_fargate.name cluster_name = aws_ecs_cluster.comm_services.name min_capacity = 1 diff --git a/services/terraform/remote/service_blob.tf b/services/terraform/remote/service_blob.tf --- a/services/terraform/remote/service_blob.tf +++ b/services/terraform/remote/service_blob.tf @@ -190,27 +190,21 @@ default_action { type = "forward" - # Production: Simple forwarding (unchanged) - target_group_arn = local.is_staging ? null : aws_lb_target_group.blob_service_http.arn - - # Staging: Weighted forwarding - dynamic "forward" { - for_each = local.is_staging ? [1] : [] - content { - target_group { - arn = aws_lb_target_group.blob_service_http.arn - weight = 0 # 0% EC2 - } + # Weighted forwarding for both environments + forward { + target_group { + arn = aws_lb_target_group.blob_service_http.arn + weight = local.is_staging ? 0 : 100 # Staging: 0% EC2, Prod: 100% EC2 + } - target_group { - arn = aws_lb_target_group.blob_service_http_fargate[0].arn - weight = 100 # 100% Fargate - } + target_group { + arn = aws_lb_target_group.blob_service_http_fargate.arn + weight = local.is_staging ? 100 : 0 # Staging: 100% Fargate, Prod: 0% Fargate + } - stickiness { - enabled = false - duration = 10 - } + stickiness { + enabled = false + duration = 10 } } } diff --git a/services/terraform/remote/service_blob_fargate.tf b/services/terraform/remote/service_blob_fargate.tf --- a/services/terraform/remote/service_blob_fargate.tf +++ b/services/terraform/remote/service_blob_fargate.tf @@ -1,6 +1,5 @@ -# Fargate task definition (staging only) +# Fargate task definition resource "aws_ecs_task_definition" "blob_service_fargate" { - count = local.is_staging ? 1 : 0 family = "blob-service-fargate-task-def" container_definitions = jsonencode([ { @@ -47,21 +46,20 @@ task_role_arn = aws_iam_role.services_ddb_full_access.arn execution_role_arn = aws_iam_role.ecs_task_execution.arn network_mode = "awsvpc" - cpu = "256" - memory = "512" + cpu = local.is_staging ? "256" : "512" + memory = local.is_staging ? "512" : "1024" requires_compatibilities = ["FARGATE"] skip_destroy = true } -# Fargate ECS Service (staging only) +# Fargate ECS Service resource "aws_ecs_service" "blob_service_fargate" { - count = local.is_staging ? 1 : 0 name = "blob-service-fargate" cluster = aws_ecs_cluster.comm_services.id launch_type = "FARGATE" - task_definition = aws_ecs_task_definition.blob_service_fargate[0].arn + task_definition = aws_ecs_task_definition.blob_service_fargate.arn force_new_deployment = true network_configuration { @@ -88,7 +86,7 @@ # HTTP load_balancer { - target_group_arn = aws_lb_target_group.blob_service_http_fargate[0].arn + target_group_arn = aws_lb_target_group.blob_service_http_fargate.arn container_name = local.blob_service_container_name container_port = local.blob_service_container_http_port } @@ -103,9 +101,8 @@ } } -# Fargate HTTP target group (staging only) +# Fargate HTTP target group resource "aws_lb_target_group" "blob_service_http_fargate" { - count = local.is_staging ? 1 : 0 name = "blob-service-http-fargate-tg" port = local.blob_service_container_http_port protocol = "HTTP" @@ -123,12 +120,12 @@ } } -# Auto-scaling for Fargate service (staging only) +# Auto-scaling for Fargate service module "blob_service_fargate_autoscaling" { source = "../modules/fargate-autoscaling" - create_resources = local.is_staging - service_name = local.is_staging ? aws_ecs_service.blob_service_fargate[0].name : "" + create_resources = true + service_name = aws_ecs_service.blob_service_fargate.name cluster_name = aws_ecs_cluster.comm_services.name min_capacity = 1 diff --git a/services/terraform/remote/service_identity.tf b/services/terraform/remote/service_identity.tf --- a/services/terraform/remote/service_identity.tf +++ b/services/terraform/remote/service_identity.tf @@ -282,27 +282,21 @@ default_action { type = "forward" - # Production: Simple forwarding (unchanged) - target_group_arn = local.is_staging ? null : aws_lb_target_group.identity_service_ws.arn - - # Staging: Weighted forwarding - dynamic "forward" { - for_each = local.is_staging ? [1] : [] - content { - target_group { - arn = aws_lb_target_group.identity_service_ws.arn - weight = 0 # 0% EC2 - } + # Weighted forwarding for both environments + forward { + target_group { + arn = aws_lb_target_group.identity_service_ws.arn + weight = local.is_staging ? 0 : 100 # Staging: 0% EC2, Prod: 100% EC2 + } - target_group { - arn = aws_lb_target_group.identity_service_ws_fargate[0].arn - weight = 100 # 100% Fargate - } + target_group { + arn = aws_lb_target_group.identity_service_ws_fargate.arn + weight = local.is_staging ? 100 : 0 # Staging: 100% Fargate, Prod: 0% Fargate + } - stickiness { - enabled = false - duration = 10 - } + stickiness { + enabled = false + duration = 10 } } } @@ -323,27 +317,21 @@ default_action { type = "forward" - # Production: Simple forwarding (unchanged) - target_group_arn = local.is_staging ? null : aws_lb_target_group.identity_service_grpc.arn - - # Staging: Weighted forwarding - dynamic "forward" { - for_each = local.is_staging ? [1] : [] - content { - target_group { - arn = aws_lb_target_group.identity_service_grpc.arn - weight = 0 # 0% EC2 - } + # Weighted forwarding for both environments + forward { + target_group { + arn = aws_lb_target_group.identity_service_grpc.arn + weight = local.is_staging ? 0 : 100 # Staging: 0% EC2, Prod: 100% EC2 + } - target_group { - arn = aws_lb_target_group.identity_service_grpc_fargate[0].arn - weight = 100 # 100% Fargate - } + target_group { + arn = aws_lb_target_group.identity_service_grpc_fargate.arn + weight = local.is_staging ? 100 : 0 # Staging: 100% Fargate, Prod: 0% Fargate + } - stickiness { - enabled = true - duration = 10 - } + stickiness { + enabled = true + duration = 10 } } } diff --git a/services/terraform/remote/service_identity_fargate.tf b/services/terraform/remote/service_identity_fargate.tf --- a/services/terraform/remote/service_identity_fargate.tf +++ b/services/terraform/remote/service_identity_fargate.tf @@ -1,6 +1,5 @@ -# Fargate task definition (staging only) +# Fargate task definition resource "aws_ecs_task_definition" "identity_service_fargate" { - count = local.is_staging ? 1 : 0 family = "identity-service-fargate-task-def" container_definitions = jsonencode([ { @@ -79,21 +78,20 @@ task_role_arn = aws_iam_role.services_ddb_full_access.arn execution_role_arn = aws_iam_role.ecs_task_execution.arn network_mode = "awsvpc" - cpu = "256" - memory = "512" + cpu = local.is_staging ? "256" : "512" + memory = local.is_staging ? "512" : "2048" requires_compatibilities = ["FARGATE"] skip_destroy = true } -# Fargate ECS Service (staging only) +# Fargate ECS Service resource "aws_ecs_service" "identity_service_fargate" { - count = local.is_staging ? 1 : 0 name = "identity-service-fargate" cluster = aws_ecs_cluster.comm_services.id launch_type = "FARGATE" - task_definition = aws_ecs_task_definition.identity_service_fargate[0].arn + task_definition = aws_ecs_task_definition.identity_service_fargate.arn force_new_deployment = true network_configuration { @@ -120,14 +118,14 @@ # WebSocket load_balancer { - target_group_arn = aws_lb_target_group.identity_service_ws_fargate[0].arn + target_group_arn = aws_lb_target_group.identity_service_ws_fargate.arn container_name = local.identity_service_container_name container_port = local.identity_service_container_ws_port } # gRPC load_balancer { - target_group_arn = aws_lb_target_group.identity_service_grpc_fargate[0].arn + target_group_arn = aws_lb_target_group.identity_service_grpc_fargate.arn container_name = local.identity_service_container_name container_port = local.identity_service_container_grpc_port } @@ -145,9 +143,8 @@ enable_ecs_managed_tags = true } -# Fargate gRPC target group (staging only) +# Fargate gRPC target group resource "aws_lb_target_group" "identity_service_grpc_fargate" { - count = local.is_staging ? 1 : 0 name = "identity-service-grpc-fargate-tg" port = local.identity_service_container_grpc_port protocol = "HTTP" @@ -173,9 +170,8 @@ } } -# Fargate WebSocket target group (staging only) +# Fargate WebSocket target group resource "aws_lb_target_group" "identity_service_ws_fargate" { - count = local.is_staging ? 1 : 0 name = "identity-service-ws-fargate-tg" port = local.identity_service_container_ws_port protocol = "HTTP" @@ -194,15 +190,15 @@ } } -# Auto-scaling for Fargate service (staging only) +# Auto-scaling for Fargate service module "identity_service_fargate_autoscaling" { source = "../modules/fargate-autoscaling" - create_resources = local.is_staging - service_name = local.is_staging ? aws_ecs_service.identity_service_fargate[0].name : "" + create_resources = true + service_name = aws_ecs_service.identity_service_fargate.name cluster_name = aws_ecs_cluster.comm_services.name - min_capacity = 1 + min_capacity = local.is_staging ? 1 : 2 max_capacity = 6 cpu_target = 35.0 memory_target = 45.0 diff --git a/services/terraform/remote/service_tunnelbroker.tf b/services/terraform/remote/service_tunnelbroker.tf --- a/services/terraform/remote/service_tunnelbroker.tf +++ b/services/terraform/remote/service_tunnelbroker.tf @@ -321,27 +321,21 @@ default_action { type = "forward" - # Production: Simple forwarding (unchanged) - target_group_arn = local.is_staging ? null : aws_lb_target_group.tunnelbroker_ws.arn - - # Staging: Weighted forwarding - dynamic "forward" { - for_each = local.is_staging ? [1] : [] - content { - target_group { - arn = aws_lb_target_group.tunnelbroker_ws.arn - weight = 0 # 0% EC2 - } + # Weighted forwarding for both environments + forward { + target_group { + arn = aws_lb_target_group.tunnelbroker_ws.arn + weight = local.is_staging ? 0 : 100 # Staging: 0% EC2, Prod: 100% EC2 + } - target_group { - arn = aws_lb_target_group.tunnelbroker_ws_fargate[0].arn - weight = 100 # 100% Fargate - } + target_group { + arn = aws_lb_target_group.tunnelbroker_ws_fargate.arn + weight = local.is_staging ? 100 : 0 # Staging: 100% Fargate, Prod: 0% Fargate + } - stickiness { - enabled = false - duration = 10 - } + stickiness { + enabled = false + duration = 10 } } } @@ -365,12 +359,12 @@ forward { target_group { arn = aws_lb_target_group.tunnelbroker_grpc.arn - weight = 0 # Switch to 0% EC2 + weight = local.is_staging ? 0 : 100 # Staging: 0% EC2, Prod: 100% EC2 } target_group { - arn = aws_lb_target_group.tunnelbroker_grpc_fargate[0].arn - weight = 100 # Switch to 100% Fargate + arn = aws_lb_target_group.tunnelbroker_grpc_fargate.arn + weight = local.is_staging ? 100 : 0 # Staging: 100% Fargate, Prod: 0% Fargate } stickiness { diff --git a/services/terraform/remote/service_tunnelbroker_fargate.tf b/services/terraform/remote/service_tunnelbroker_fargate.tf --- a/services/terraform/remote/service_tunnelbroker_fargate.tf +++ b/services/terraform/remote/service_tunnelbroker_fargate.tf @@ -1,6 +1,5 @@ -# Fargate task definition (staging only) +# Fargate task definition resource "aws_ecs_task_definition" "tunnelbroker_fargate" { - count = local.is_staging ? 1 : 0 family = "tunnelbroker-fargate-task-def" container_definitions = jsonencode([ { @@ -91,21 +90,20 @@ task_role_arn = aws_iam_role.services_ddb_full_access.arn execution_role_arn = aws_iam_role.ecs_task_execution.arn network_mode = "awsvpc" - cpu = "256" - memory = "512" + cpu = local.is_staging ? "256" : "512" + memory = local.is_staging ? "512" : "1024" requires_compatibilities = ["FARGATE"] skip_destroy = true } -# Fargate ECS Service (staging only) +# Fargate ECS Service resource "aws_ecs_service" "tunnelbroker_fargate" { - count = local.is_staging ? 1 : 0 name = "tunnelbroker-fargate" cluster = aws_ecs_cluster.comm_services.id launch_type = "FARGATE" - task_definition = aws_ecs_task_definition.tunnelbroker_fargate[0].arn + task_definition = aws_ecs_task_definition.tunnelbroker_fargate.arn force_new_deployment = true network_configuration { @@ -132,16 +130,19 @@ # Websocket load_balancer { - target_group_arn = aws_lb_target_group.tunnelbroker_ws_fargate[0].arn + target_group_arn = aws_lb_target_group.tunnelbroker_ws_fargate.arn container_name = local.tunnelbroker_config.container_name container_port = local.tunnelbroker_config.websocket_port } # gRPC (only exists in staging) - load_balancer { - target_group_arn = aws_lb_target_group.tunnelbroker_grpc_fargate[0].arn - container_name = local.tunnelbroker_config.container_name - container_port = local.tunnelbroker_config.grpc_port + dynamic "load_balancer" { + for_each = aws_lb_listener.tunnelbroker_grpc + content { + target_group_arn = aws_lb_target_group.tunnelbroker_grpc_fargate.arn + container_name = local.tunnelbroker_config.container_name + container_port = local.tunnelbroker_config.grpc_port + } } deployment_circuit_breaker { @@ -154,9 +155,8 @@ } } -# Fargate WebSocket target group (staging only) +# Fargate WebSocket target group resource "aws_lb_target_group" "tunnelbroker_ws_fargate" { - count = local.is_staging ? 1 : 0 name = "tunnelbroker-ws-fargate-tg" port = local.tunnelbroker_config.websocket_port protocol = "HTTP" @@ -175,9 +175,8 @@ } } -# Fargate gRPC target group (staging only) +# Fargate gRPC target group resource "aws_lb_target_group" "tunnelbroker_grpc_fargate" { - count = local.is_staging ? 1 : 0 name = "tunnelbroker-grpc-fargate-tg" port = local.tunnelbroker_config.grpc_port protocol = "HTTP" @@ -192,15 +191,15 @@ } } -# Auto-scaling for Fargate service (staging only) +# Auto-scaling for Fargate service module "tunnelbroker_fargate_autoscaling" { source = "../modules/fargate-autoscaling" - create_resources = local.is_staging - service_name = local.is_staging ? aws_ecs_service.tunnelbroker_fargate[0].name : "" + create_resources = true + service_name = aws_ecs_service.tunnelbroker_fargate.name cluster_name = aws_ecs_cluster.comm_services.name - min_capacity = 1 + min_capacity = local.is_staging ? 1 : 2 max_capacity = 8 cpu_target = 30.0 memory_target = 40.0