Page MenuHomePhorge

D15490.1765014224.diff
No OneTemporary

Size
29 KB
Referenced Files
None
Subscribers
None

D15490.1765014224.diff

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
@@ -12,6 +12,9 @@
# URL accessible by other services in the same Service Connect namespace
# This renders to 'http://backup-service:50052'
backup_local_url = "http://${local.backup_sc_dns_name}:${local.backup_service_container_http_port}"
+
+ # Fargate-specific URL for Fargate services to communicate with Fargate backup service
+ backup_fargate_url = "http://${local.backup_sc_dns_name}-fargate:${local.backup_service_container_http_port}"
}
resource "aws_ecs_task_definition" "backup_service" {
@@ -182,8 +185,31 @@
certificate_arn = data.aws_acm_certificate.backup_service.arn
default_action {
- type = "forward"
- target_group_arn = aws_lb_target_group.backup_service_http.arn
+ 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 = 100 # 100% EC2
+ }
+
+ target_group {
+ arn = aws_lb_target_group.backup_service_http_fargate[0].arn
+ weight = 0 # 0% Fargate
+ }
+
+ stickiness {
+ enabled = false
+ duration = 10
+ }
+ }
+ }
}
lifecycle {
diff --git a/services/terraform/remote/service_backup_fargate.tf b/services/terraform/remote/service_backup_fargate.tf
new file mode 100644
--- /dev/null
+++ b/services/terraform/remote/service_backup_fargate.tf
@@ -0,0 +1,144 @@
+# Fargate task definition (staging only)
+resource "aws_ecs_task_definition" "backup_service_fargate" {
+ count = local.is_staging ? 1 : 0
+ family = "backup-service-fargate-task-def"
+ container_definitions = jsonencode([
+ {
+ name = local.backup_service_container_name
+ image = local.backup_service_server_image
+ essential = true
+ portMappings = [
+ {
+ name = local.backup_sc_port_name
+ containerPort = local.backup_service_container_http_port
+ protocol = "tcp"
+ appProtocol = "http"
+ },
+ ]
+ environment = [
+ {
+ name = "RUST_LOG"
+ value = local.is_staging ? "info,backup=debug,comm_lib=debug" : "info"
+ },
+ {
+ name = "BLOB_SERVICE_URL",
+ value = local.blob_fargate_url
+ },
+ {
+ name = "IDENTITY_SERVICE_ENDPOINT",
+ value = local.identity_fargate_url
+ },
+ {
+ name = "COMM_SERVICES_USE_JSON_LOGS",
+ value = local.comm_services_use_json_logs
+ }
+ ]
+ logConfiguration = {
+ "logDriver" = "awslogs"
+ "options" = {
+ "awslogs-create-group" = "true"
+ "awslogs-group" = "/ecs/backup-service-fargate-task-def"
+ "awslogs-region" = "us-east-2"
+ "awslogs-stream-prefix" = "ecs"
+ }
+ }
+ }
+ ])
+ 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"
+ requires_compatibilities = ["FARGATE"]
+
+ skip_destroy = true
+}
+
+# Fargate ECS Service (staging only)
+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
+ force_new_deployment = true
+
+ network_configuration {
+ subnets = [
+ aws_subnet.public_a.id,
+ aws_subnet.public_b.id,
+ aws_subnet.public_c.id,
+ ]
+ security_groups = [aws_security_group.backup_service.id]
+ assign_public_ip = true
+ }
+
+ service_connect_configuration {
+ enabled = true
+ service {
+ discovery_name = "${local.backup_sc_dns_name}-fargate"
+ port_name = local.backup_sc_port_name
+ client_alias {
+ port = local.backup_service_container_http_port
+ dns_name = "${local.backup_sc_dns_name}-fargate"
+ }
+ }
+ }
+
+ # HTTP
+ load_balancer {
+ target_group_arn = aws_lb_target_group.backup_service_http_fargate[0].arn
+ container_name = local.backup_service_container_name
+ container_port = local.backup_service_container_http_port
+ }
+
+ deployment_circuit_breaker {
+ enable = true
+ rollback = true
+ }
+
+ lifecycle {
+ ignore_changes = [desired_count]
+ }
+
+ enable_execute_command = true
+ enable_ecs_managed_tags = true
+}
+
+# Fargate HTTP target group (staging only)
+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"
+ vpc_id = aws_vpc.default.id
+ target_type = "ip"
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+
+ protocol = "HTTP"
+ path = "/health"
+ matcher = "200-204"
+ }
+}
+
+# Auto-scaling for Fargate service (staging only)
+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 : ""
+ cluster_name = aws_ecs_cluster.comm_services.name
+
+ min_capacity = 1
+ max_capacity = 4
+ cpu_target = 40.0
+ memory_target = 50.0
+
+ scale_in_cooldown = 300 # 5 minutes
+ scale_out_cooldown = 60 # 1 minute
+}
\ No newline at end of file
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
@@ -12,6 +12,9 @@
# This renders to 'http://blob-service:50053'
blob_local_url = "http://${local.blob_sc_dns_name}:${local.blob_service_container_http_port}"
+ # Fargate-specific URL for Fargate services to communicate with Fargate blob service
+ blob_fargate_url = "http://${local.blob_sc_dns_name}-fargate:${local.blob_service_container_http_port}"
+
blob_service_container_grpc_port = 50051
blob_service_grpc_public_port = 50053
blob_service_domain_name = "blob.${local.root_domain}"
@@ -185,8 +188,31 @@
certificate_arn = data.aws_acm_certificate.blob_service.arn
default_action {
- type = "forward"
- target_group_arn = aws_lb_target_group.blob_service_http.arn
+ 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 = 100 # 100% EC2
+ }
+
+ target_group {
+ arn = aws_lb_target_group.blob_service_http_fargate[0].arn
+ weight = 0 # 0% Fargate
+ }
+
+ stickiness {
+ enabled = false
+ duration = 10
+ }
+ }
+ }
}
lifecycle {
diff --git a/services/terraform/remote/service_blob_fargate.tf b/services/terraform/remote/service_blob_fargate.tf
new file mode 100644
--- /dev/null
+++ b/services/terraform/remote/service_blob_fargate.tf
@@ -0,0 +1,141 @@
+# Fargate task definition (staging only)
+resource "aws_ecs_task_definition" "blob_service_fargate" {
+ count = local.is_staging ? 1 : 0
+ family = "blob-service-fargate-task-def"
+ container_definitions = jsonencode([
+ {
+ name = local.blob_service_container_name
+ image = local.blob_service_server_image
+ essential = true
+ portMappings = [
+ {
+ name = local.blob_sc_port_name
+ containerPort = local.blob_service_container_http_port
+ protocol = "tcp"
+ appProtocol = "http"
+ }
+ ]
+ environment = [
+ {
+ name = "RUST_LOG"
+ value = local.is_staging ? "info,blob=debug,comm_lib=debug" : "info"
+ },
+ {
+ name = "BLOB_S3_BUCKET_NAME",
+ value = local.blob_service_s3_bucket
+ },
+ {
+ name = "IDENTITY_SERVICE_ENDPOINT",
+ value = local.identity_fargate_url
+ },
+ {
+ name = "COMM_SERVICES_USE_JSON_LOGS",
+ value = local.comm_services_use_json_logs
+ }
+ ]
+ logConfiguration = {
+ "logDriver" = "awslogs"
+ "options" = {
+ "awslogs-create-group" = "true"
+ "awslogs-group" = "/ecs/blob-service-fargate-task-def"
+ "awslogs-region" = "us-east-2"
+ "awslogs-stream-prefix" = "ecs"
+ }
+ }
+ }
+ ])
+ 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"
+ requires_compatibilities = ["FARGATE"]
+
+ skip_destroy = true
+}
+
+# Fargate ECS Service (staging only)
+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
+ force_new_deployment = true
+
+ network_configuration {
+ subnets = [
+ aws_subnet.public_a.id,
+ aws_subnet.public_b.id,
+ aws_subnet.public_c.id,
+ ]
+ security_groups = [aws_security_group.blob_service.id]
+ assign_public_ip = true
+ }
+
+ service_connect_configuration {
+ enabled = true
+ service {
+ discovery_name = "${local.blob_sc_dns_name}-fargate"
+ port_name = local.blob_sc_port_name
+ client_alias {
+ port = local.blob_service_container_http_port
+ dns_name = "${local.blob_sc_dns_name}-fargate"
+ }
+ }
+ }
+
+ # HTTP
+ load_balancer {
+ target_group_arn = aws_lb_target_group.blob_service_http_fargate[0].arn
+ container_name = local.blob_service_container_name
+ container_port = local.blob_service_container_http_port
+ }
+
+ deployment_circuit_breaker {
+ enable = true
+ rollback = true
+ }
+
+ lifecycle {
+ ignore_changes = [desired_count]
+ }
+}
+
+# Fargate HTTP target group (staging only)
+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"
+ vpc_id = aws_vpc.default.id
+ target_type = "ip"
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+
+ protocol = "HTTP"
+ path = "/health"
+ matcher = "200-499"
+ }
+}
+
+# Auto-scaling for Fargate service (staging only)
+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 : ""
+ cluster_name = aws_ecs_cluster.comm_services.name
+
+ min_capacity = 1
+ max_capacity = 4
+ cpu_target = 35.0
+ memory_target = 45.0
+
+ scale_in_cooldown = 300 # 5 minutes
+ scale_out_cooldown = 60 # 1 minute
+}
\ No newline at end of file
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
@@ -16,6 +16,9 @@
# This renders to e.g. 'http://identity-service:50054'
identity_local_url = "http://${local.identity_sc_dns_name}:${local.identity_service_container_grpc_port}"
+ # Fargate-specific URL for Fargate services to communicate with Fargate identity service
+ identity_fargate_url = "http://${local.identity_sc_dns_name}-fargate:${local.identity_service_container_grpc_port}"
+
# Port that is exposed to the public SSL endpoint (appended to domain name)
identity_service_grpc_public_port = 50054
identity_service_domain_name = "identity.${local.root_domain}"
@@ -277,8 +280,31 @@
certificate_arn = data.aws_acm_certificate.identity_service.arn
default_action {
- type = "forward"
- target_group_arn = aws_lb_target_group.identity_service_ws.arn
+ 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 = 100 # 100% EC2
+ }
+
+ target_group {
+ arn = aws_lb_target_group.identity_service_ws_fargate[0].arn
+ weight = 0 # 0% Fargate
+ }
+
+ stickiness {
+ enabled = false
+ duration = 10
+ }
+ }
+ }
}
lifecycle {
@@ -295,8 +321,31 @@
certificate_arn = data.aws_acm_certificate.identity_service.arn
default_action {
- type = "forward"
- target_group_arn = aws_lb_target_group.identity_service_grpc.arn
+ 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 = 100 # Start with 100% EC2
+ }
+
+ target_group {
+ arn = aws_lb_target_group.identity_service_grpc_fargate[0].arn
+ weight = 0 # Start with 0% Fargate
+ }
+
+ stickiness {
+ enabled = true
+ duration = 10
+ }
+ }
+ }
}
lifecycle {
diff --git a/services/terraform/remote/service_identity_fargate.tf b/services/terraform/remote/service_identity_fargate.tf
new file mode 100644
--- /dev/null
+++ b/services/terraform/remote/service_identity_fargate.tf
@@ -0,0 +1,212 @@
+# Fargate task definition (staging only)
+resource "aws_ecs_task_definition" "identity_service_fargate" {
+ count = local.is_staging ? 1 : 0
+ family = "identity-service-fargate-task-def"
+ container_definitions = jsonencode([
+ {
+ name = local.identity_service_container_name
+ image = local.identity_service_server_image
+ essential = true
+ portMappings = [
+ {
+ name = local.identity_sc_port_name
+ containerPort = local.identity_service_container_grpc_port
+ protocol = "tcp"
+ appProtocol = "grpc"
+ },
+ {
+ name = local.identity_sc_ws_port_name
+ containerPort = local.identity_service_container_ws_port
+ protocol = "tcp"
+ appProtocol = "http"
+ }
+ ]
+ environment = [
+ {
+ name = "RUST_LOG"
+ value = local.is_staging ? "info,identity=debug,comm_lib=debug" : "info"
+ },
+ {
+ name = "KEYSERVER_PUBLIC_KEY"
+ value = nonsensitive(local.secrets["keyserverPublicKey"])
+ },
+ {
+ name = "TUNNELBROKER_GRPC_ENDPOINT"
+ value = local.tunnelbroker_fargate_grpc_url
+ },
+ {
+ name = "BACKUP_SERVICE_URL",
+ value = local.backup_fargate_url
+ },
+ {
+ name = "BLOB_SERVICE_URL",
+ value = local.blob_fargate_url
+ },
+ {
+ name = "OPENSEARCH_ENDPOINT"
+ value = module.shared.opensearch_domain_identity.endpoint
+ },
+ {
+ name = "ALLOW_ORIGIN_LIST"
+ value = local.is_staging ? local.staging_allow_origin_list : local.production_allow_origin_list
+ },
+ {
+ name = "COMM_SERVICES_USE_JSON_LOGS",
+ value = local.comm_services_use_json_logs
+ },
+ {
+ name = "REDACT_SENSITIVE_DATA",
+ value = local.is_staging ? "false" : "true"
+ }
+ ]
+ secrets = [
+ {
+ name = "OPAQUE_SERVER_SETUP"
+ valueFrom = data.aws_secretsmanager_secret.identity_server_setup.arn
+ }
+ ]
+ logConfiguration = {
+ "logDriver" = "awslogs"
+ "options" = {
+ "awslogs-create-group" = "true"
+ "awslogs-group" = "/ecs/identity-service-fargate-task-def"
+ "awslogs-region" = "us-east-2"
+ "awslogs-stream-prefix" = "ecs"
+ }
+ }
+ }
+ ])
+ 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"
+ requires_compatibilities = ["FARGATE"]
+
+ skip_destroy = true
+}
+
+# Fargate ECS Service (staging only)
+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
+ force_new_deployment = true
+
+ network_configuration {
+ subnets = [
+ aws_subnet.public_a.id,
+ aws_subnet.public_b.id,
+ aws_subnet.public_c.id,
+ ]
+ security_groups = [aws_security_group.identity_service.id]
+ assign_public_ip = true
+ }
+
+ service_connect_configuration {
+ enabled = true
+ service {
+ discovery_name = "${local.identity_sc_dns_name}-fargate"
+ port_name = local.identity_sc_port_name
+ client_alias {
+ port = local.identity_service_container_grpc_port
+ dns_name = "${local.identity_sc_dns_name}-fargate"
+ }
+ }
+ }
+
+ # WebSocket
+ load_balancer {
+ target_group_arn = aws_lb_target_group.identity_service_ws_fargate[0].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
+ container_name = local.identity_service_container_name
+ container_port = local.identity_service_container_grpc_port
+ }
+
+ deployment_circuit_breaker {
+ enable = true
+ rollback = true
+ }
+
+ lifecycle {
+ ignore_changes = [desired_count]
+ }
+
+ enable_execute_command = true
+ enable_ecs_managed_tags = true
+}
+
+# Fargate gRPC target group (staging only)
+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"
+ protocol_version = "HTTP2"
+ vpc_id = aws_vpc.default.id
+ target_type = "ip"
+
+ stickiness {
+ type = "lb_cookie"
+ cookie_duration = 10
+ enabled = true
+ }
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+
+ protocol = "HTTP"
+ port = "traffic-port"
+ path = "/"
+ matcher = "200-499"
+ }
+}
+
+# Fargate WebSocket target group (staging only)
+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"
+ protocol_version = "HTTP1"
+ vpc_id = aws_vpc.default.id
+ target_type = "ip"
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+
+ protocol = "HTTP"
+ path = "/health"
+ matcher = "200"
+ }
+}
+
+# Auto-scaling for Fargate service (staging only)
+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 : ""
+ cluster_name = aws_ecs_cluster.comm_services.name
+
+ min_capacity = 1
+ max_capacity = 6
+ cpu_target = 35.0
+ memory_target = 45.0
+
+ scale_in_cooldown = 300 # 5 minutes
+ scale_out_cooldown = 60 # 1 minute
+}
\ No newline at end of file
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
@@ -15,6 +15,9 @@
# Used for other services to connect to Tunnelbroker gRPC endpoint
tunnelbroker_local_grpc_url = "http://${local.tunnelbroker_config.local_dns_name}:${local.tunnelbroker_config.grpc_port}"
+ # Fargate-specific URL for Fargate services to communicate with Fargate tunnelbroker
+ tunnelbroker_fargate_grpc_url = "http://${local.tunnelbroker_config.local_dns_name}-fargate:${local.tunnelbroker_config.grpc_port}"
+
# utility locals
tunnelbroker_docker_image = "${local.tunnelbroker_config.docker_image}:${local.tunnelbroker_config.docker_tag}"
rabbitmq_password = local.secrets.amqpPassword[local.environment]
@@ -316,8 +319,31 @@
certificate_arn = data.aws_acm_certificate.tunnelbroker.arn
default_action {
- type = "forward"
- target_group_arn = aws_lb_target_group.tunnelbroker_ws.arn
+ 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 = 100 # Switch back to 100% EC2
+ }
+
+ target_group {
+ arn = aws_lb_target_group.tunnelbroker_ws_fargate[0].arn
+ weight = 0 # Switch back to 0% Fargate
+ }
+
+ stickiness {
+ enabled = false
+ duration = 10
+ }
+ }
+ }
}
lifecycle {
@@ -335,8 +361,23 @@
certificate_arn = data.aws_acm_certificate.tunnelbroker.arn
default_action {
- type = "forward"
- target_group_arn = aws_lb_target_group.tunnelbroker_grpc.arn
+ type = "forward"
+ forward {
+ target_group {
+ arn = aws_lb_target_group.tunnelbroker_grpc.arn
+ weight = 100 # 100% EC2
+ }
+
+ target_group {
+ arn = aws_lb_target_group.tunnelbroker_grpc_fargate[0].arn
+ weight = 0 # 0% Fargate
+ }
+
+ stickiness {
+ enabled = false
+ duration = 10
+ }
+ }
}
lifecycle {
diff --git a/services/terraform/remote/service_tunnelbroker_fargate.tf b/services/terraform/remote/service_tunnelbroker_fargate.tf
new file mode 100644
--- /dev/null
+++ b/services/terraform/remote/service_tunnelbroker_fargate.tf
@@ -0,0 +1,210 @@
+# Fargate task definition (staging only)
+resource "aws_ecs_task_definition" "tunnelbroker_fargate" {
+ count = local.is_staging ? 1 : 0
+ family = "tunnelbroker-fargate-task-def"
+ container_definitions = jsonencode([
+ {
+ name = local.tunnelbroker_config.container_name
+ image = local.tunnelbroker_docker_image
+ essential = true
+ portMappings = [
+ {
+ name = "tunnelbroker_ws"
+ containerPort = local.tunnelbroker_config.websocket_port
+ protocol = "tcp"
+ appProtocol = "http"
+ },
+ {
+ name = local.tunnelbroker_config.grpc_port_name
+ containerPort = local.tunnelbroker_config.grpc_port
+ protocol = "tcp"
+ appProtocol = "grpc"
+ }
+ ]
+ environment = [
+ {
+ name = "RUST_LOG"
+ value = local.is_staging ? "info,tunnelbroker=debug,comm_lib=debug" : "info"
+ },
+ {
+ name = "AMQP_URI",
+ value = local.amqp_endpoint
+ },
+ {
+ name = "AMQP_USERNAME"
+ value = "comm"
+ },
+ {
+ name = "AMQP_PASSWORD"
+ value = nonsensitive(local.rabbitmq_password)
+ },
+ {
+ name = "COMM_TUNNELBROKER_IDENTITY_ENDPOINT",
+ value = local.identity_fargate_url
+ },
+ {
+ name = "BLOB_SERVICE_URL",
+ value = local.blob_fargate_url
+ },
+ {
+ name = "BLOB_SERVICE_PUBLIC_URL",
+ value = "https://${local.blob_service_domain_name}"
+ },
+ {
+ name = "COMM_SERVICES_USE_JSON_LOGS",
+ value = local.comm_services_use_json_logs
+ },
+ {
+ name = "REDACT_SENSITIVE_DATA",
+ value = local.is_staging ? "false" : "true"
+ }
+ ]
+ secrets = [
+ {
+ name = "APNS_CONFIG"
+ valueFrom = data.aws_secretsmanager_secret.tunnelbroker_apns.arn
+ },
+ {
+ name = "FCM_CONFIG"
+ valueFrom = data.aws_secretsmanager_secret.tunnelbroker_fcm.arn
+ },
+ {
+ name = "WEB_PUSH_CONFIG"
+ valueFrom = data.aws_secretsmanager_secret.tunnelbroker_web_push.arn
+ },
+ {
+ name = "WNS_CONFIG"
+ valueFrom = data.aws_secretsmanager_secret.tunnelbroker_wns.arn
+ }
+ ]
+ logConfiguration = {
+ "logDriver" = "awslogs"
+ "options" = {
+ "awslogs-create-group" = "true"
+ "awslogs-group" = "/ecs/tunnelbroker-fargate-task-def"
+ "awslogs-region" = "us-east-2"
+ "awslogs-stream-prefix" = "ecs"
+ }
+ }
+ }
+ ])
+ 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"
+ requires_compatibilities = ["FARGATE"]
+
+ skip_destroy = true
+}
+
+# Fargate ECS Service (staging only)
+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
+ force_new_deployment = true
+
+ network_configuration {
+ subnets = [
+ aws_subnet.public_a.id,
+ aws_subnet.public_b.id,
+ aws_subnet.public_c.id,
+ ]
+ security_groups = [aws_security_group.tunnelbroker.id]
+ assign_public_ip = true
+ }
+
+ service_connect_configuration {
+ enabled = true
+ service {
+ discovery_name = "${local.tunnelbroker_config.local_dns_name}-fargate"
+ port_name = local.tunnelbroker_config.grpc_port_name
+ client_alias {
+ port = local.tunnelbroker_config.grpc_port
+ dns_name = "${local.tunnelbroker_config.local_dns_name}-fargate"
+ }
+ }
+ }
+
+ # Websocket
+ load_balancer {
+ target_group_arn = aws_lb_target_group.tunnelbroker_ws_fargate[0].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
+ }
+
+ deployment_circuit_breaker {
+ enable = true
+ rollback = true
+ }
+
+ lifecycle {
+ ignore_changes = [desired_count]
+ }
+}
+
+# Fargate WebSocket target group (staging only)
+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"
+ protocol_version = "HTTP1"
+ vpc_id = aws_vpc.default.id
+ target_type = "ip"
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+
+ protocol = "HTTP"
+ path = "/health"
+ matcher = "200"
+ }
+}
+
+# Fargate gRPC target group (staging only)
+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"
+ protocol_version = "GRPC"
+ vpc_id = aws_vpc.default.id
+ target_type = "ip"
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+ }
+}
+
+# Auto-scaling for Fargate service (staging only)
+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 : ""
+ cluster_name = aws_ecs_cluster.comm_services.name
+
+ min_capacity = 1
+ max_capacity = 8
+ cpu_target = 30.0
+ memory_target = 40.0
+
+ scale_in_cooldown = 300 # 5 minutes
+ scale_out_cooldown = 60 # 1 minute
+}
\ No newline at end of file

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 6, 9:43 AM (17 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5828949
Default Alt Text
D15490.1765014224.diff (29 KB)

Event Timeline