diff --git a/services/terraform/self-host/aws_lb.tf b/services/terraform/self-host/aws_lb.tf new file mode 100644 index 000000000..f85eb2252 --- /dev/null +++ b/services/terraform/self-host/aws_lb.tf @@ -0,0 +1,82 @@ +resource "aws_security_group" "lb_sg" { + name = "lb-sg" + description = "Security group for keyserver load balancer" + vpc_id = local.vpc_id + + ingress { + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_lb_target_group" "keyserver_service" { + name = "keyserver-service-ecs-tg" + port = 3000 + protocol = "HTTP" + vpc_id = local.vpc_id + + # "awsvpc" network mode requires target type set to ip + target_type = "ip" + + stickiness { + type = "lb_cookie" + cookie_duration = 86500 + enabled = true + } + + health_check { + enabled = true + healthy_threshold = 2 + unhealthy_threshold = 3 + + protocol = "HTTP" + path = "/health" + matcher = "200-299" + } +} + +resource "aws_lb" "keyserver_service" { + load_balancer_type = "application" + name = "keyserver-service-lb" + security_groups = [aws_security_group.lb_sg.id] + + internal = false + subnets = local.vpc_subnets +} + +resource "aws_lb_listener" "keyserver_service" { + load_balancer_arn = aws_lb.keyserver_service.arn + port = "443" + protocol = "HTTPS" + ssl_policy = "ELBSecurityPolicy-2016-08" + certificate_arn = data.aws_acm_certificate.keyserver_service.arn + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.keyserver_service.arn + } + + lifecycle { + ignore_changes = [default_action[0].forward[0].stickiness[0].duration] + replace_triggered_by = [aws_lb_target_group.keyserver_service] + } +} + + +data "aws_acm_certificate" "keyserver_service" { + domain = var.domain_name + statuses = ["ISSUED"] +} + +output "keyserver_service_load_balancer_dns_name" { + value = aws_lb.keyserver_service.dns_name +} diff --git a/services/terraform/self-host/keyserver_primary.tf b/services/terraform/self-host/keyserver_primary.tf index 2a899500c..bbc2dce0a 100644 --- a/services/terraform/self-host/keyserver_primary.tf +++ b/services/terraform/self-host/keyserver_primary.tf @@ -1,155 +1,179 @@ locals { keyserver_service_image_tag = "0.1" keyserver_service_server_image = "commapp/keyserver:${local.keyserver_service_image_tag}" keyserver_service_container_name = "keyserver-primary" } resource "aws_cloudwatch_log_group" "ecs_log_group" { name = "/ecs/keyserver-primary-task-def" retention_in_days = 7 } output "mariadb_address" { value = aws_db_instance.mariadb.address } resource "aws_ecs_task_definition" "keyserver_service" { network_mode = "awsvpc" family = "keyserver-primary-task-def" requires_compatibilities = ["FARGATE"] task_role_arn = aws_iam_role.ecs_task_role.arn execution_role_arn = aws_iam_role.ecs_task_execution.arn cpu = "2048" memory = "4096" ephemeral_storage { size_in_gib = 40 } container_definitions = jsonencode([ { name = local.keyserver_service_container_name image = local.keyserver_service_server_image essential = true portMappings = [ { name = "keyserver-port" containerPort = 3000 + hostPort = 3000, protocol = "tcp" }, - { - name = "http-port" - containerPort = 80 - protocol = "tcp" - appProtocol = "http" - }, + ] environment = [ + { + name = "COMM_LISTEN_ADDR" + value = "0.0.0.0" + }, { name = "COMM_DATABASE_HOST" value = "${aws_db_instance.mariadb.address}" }, { name = "COMM_DATABASE_DATABASE" value = "comm" }, { name = "COMM_DATABASE_PORT" value = "3307" }, { name = "COMM_DATABASE_USER" value = "${var.mariadb_username}" }, { name = "COMM_DATABASE_PASSWORD" value = "${var.mariadb_password}" }, { name = "COMM_JSONCONFIG_secrets_user_credentials" value = jsonencode(var.keyserver_user_credentials) }, { name = "COMM_JSONCONFIG_facts_webapp_cors" value = jsonencode({ "domain" : "https://web.comm.app" }) }, + { + name = "COMM_JSONCONFIG_facts_keyserver_url" + value = jsonencode({ + "baseDomain" : "https://${var.domain_name}", + "basePath" : "/", + "baseRoutePath" : "/", + "https" : false, + "proxy" : "none" + }) + }, { name = "COMM_JSONCONFIG_secrets_identity_service_config", value = jsonencode({ "identitySocketAddr" : "${var.identity_socket_address}" }) }, ] logConfiguration = { "logDriver" = "awslogs" "options" = { "awslogs-create-group" = "true" "awslogs-group" = aws_cloudwatch_log_group.ecs_log_group.name "awslogs-stream-prefix" = "ecs" "awslogs-region" = "${var.region}" } } linuxParameters = { initProcessEnabled = true } } ]) runtime_platform { cpu_architecture = "ARM64" operating_system_family = "LINUX" } skip_destroy = false } resource "aws_ecs_service" "keyserver_primary_service" { name = "keyserver-primary-service" cluster = aws_ecs_cluster.keyserver_cluster.id task_definition = aws_ecs_task_definition.keyserver_service.arn launch_type = "FARGATE" enable_execute_command = true enable_ecs_managed_tags = true force_new_deployment = true desired_count = 1 network_configuration { subnets = local.vpc_subnets security_groups = [aws_security_group.keyserver_service.id] assign_public_ip = true } + load_balancer { + target_group_arn = aws_lb_target_group.keyserver_service.arn + container_name = local.keyserver_service_container_name + container_port = 3000 + } + deployment_circuit_breaker { enable = true rollback = true } } resource "aws_security_group" "keyserver_service" { name = "keyserver-service-ecs-sg" vpc_id = local.vpc_id - # Allow all inbound traffic. This is temporary until load balancer is configured + # Allow all inbound traffic on port 3000 ingress { - from_port = 0 - to_port = 65535 + from_port = 3000 + to_port = 3000 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } + ingress { + description = "Allow inbound traffic from any IPv6 address" + from_port = 3000 + to_port = 3000 + protocol = "tcp" + ipv6_cidr_blocks = ["::/0"] + } + # Allow all outbound traffic egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } lifecycle { create_before_destroy = true } } diff --git a/services/terraform/self-host/variables.tf b/services/terraform/self-host/variables.tf index aef201744..d9a2bb21e 100644 --- a/services/terraform/self-host/variables.tf +++ b/services/terraform/self-host/variables.tf @@ -1,54 +1,59 @@ variable "keyserver_user_credentials" { description = "Credentials for user authentication" type = object({ username = string password = string usingIdentityCredentials = optional(bool) force = optional(bool) }) } +variable "domain_name" { + description = "Domain name for your keyserver" + type = string +} + variable "mariadb_username" { description = "MariaDB username" type = string sensitive = true } variable "mariadb_password" { description = "MariaDB password" type = string sensitive = true } variable "region" { description = "The AWS region to deploy your keyserver in" type = string default = "us-west-1" } variable "allowed_ip" { description = "IP address" type = string } variable "user_created_vpc" { description = "Use non-default vpc and subnets" } variable "availability_zone_1" { description = "First availability zone for vpc subnet if user created vpc" type = string default = "us-west-1b" } variable "availability_zone_2" { description = "Second availability zone for vpc subnet if user created vpc" type = string default = "us-west-1c" } variable "identity_socket_address" { description = "The socket address to access the identity service" type = string default = "https://identity.commtechnologies.org:50054" }