diff --git a/services/docker-compose.yml b/services/docker-compose.yml index 1db479b00..a74367e2a 100644 --- a/services/docker-compose.yml +++ b/services/docker-compose.yml @@ -1,109 +1,109 @@ version: '3.9' volumes: localstack: services: # tunnelbroker tunnelbroker-server: depends_on: - localstack - rabbitmq build: dockerfile: services/tunnelbroker/Dockerfile context: ../ image: commapp/tunnelbroker-server:0.5 ports: - '${COMM_SERVICES_PORT_TUNNELBROKER}:50051' volumes: - $HOME/.aws/config:/home/comm/.aws/config:ro - $HOME/.aws/credentials:/home/comm/.aws/credentials:ro # backup backup-server: platform: linux/amd64 depends_on: - localstack - blob-server build: dockerfile: services/backup/Dockerfile context: ../ image: commapp/backup-server:0.2 ports: - '${COMM_SERVICES_PORT_BACKUP}:50052' volumes: - $HOME/.aws/config:/home/comm/.aws/config:ro - $HOME/.aws/credentials:/home/comm/.aws/credentials:ro # blob blob-server: platform: linux/amd64 depends_on: - localstack build: dockerfile: services/blob/Dockerfile context: ../ image: commapp/blob-server:0.1 ports: - '${COMM_SERVICES_PORT_BLOB}:50053' volumes: - $HOME/.aws/config:/home/comm/.aws/config:ro - $HOME/.aws/credentials:/home/comm/.aws/credentials:ro # identity identity-server: platform: linux/amd64 depends_on: - localstack build: dockerfile: services/identity/Dockerfile context: ../ image: commapp/identity-server:0.1 ports: - '${COMM_SERVICES_PORT_IDENTITY}:50054' # feature-flags feature-flags-server: depends_on: - localstack build: dockerfile: services/feature-flags/Dockerfile context: ../ - image: commapp/feature-flags:0.1 + image: commapp/feature-flags:0.1.1 ports: - - '${COMM_SERVICES_PORT_FEATURE_FLAGS}:50051' + - '${COMM_SERVICES_PORT_FEATURE_FLAGS}:50055' volumes: - $HOME/.aws/config:/home/comm/.aws/config:ro - $HOME/.aws/credentials:/home/comm/.aws/credentials:ro # reports reports-server: platform: linux/amd64 depends_on: - localstack - blob-server build: dockerfile: services/reports/Dockerfile context: ../ image: commapp/reports-server:0.1 ports: - '${COMM_SERVICES_PORT_REPORTS}:50056' volumes: - $HOME/.aws/config:/home/comm/.aws/config:ro - $HOME/.aws/credentials:/home/comm/.aws/credentials:ro # localstack localstack: image: localstack/localstack hostname: localstack ports: - '4566:4566' environment: - SERVICES=s3,dynamodb - DATA_DIR=/tmp/localstack - HOSTNAME_EXTERNAL=localstack volumes: - localstack:/tmp/localstack # RabbitMQ rabbitmq: image: rabbitmq:3-management hostname: rabbitmq ports: - '5672:5672' - '5671:5671' - '15672:15672' environment: - RABBITMQ_DEFAULT_USER=comm - RABBITMQ_DEFAULT_PASS=comm diff --git a/services/feature-flags/Dockerfile b/services/feature-flags/Dockerfile index a27b5dbe4..5fc66ffe7 100644 --- a/services/feature-flags/Dockerfile +++ b/services/feature-flags/Dockerfile @@ -1,36 +1,35 @@ FROM rust:1.70-bullseye as builder RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ build-essential cmake git libgtest-dev libssl-dev zlib1g-dev \ && rm -rf /var/lib/apt/lists/* WORKDIR /home/root/app/feature-flags ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse # Copy actual application sources COPY services/comm-services-lib ../comm-services-lib COPY services/feature-flags ./ RUN cargo install --locked --path . # Runner stage FROM debian:bullseye-slim as runner # Update dependencies, install ca-certificates which are required for TLS RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ ca-certificates \ && rm -rf /var/lib/apt/lists/* # Only copy built binary from builder stage COPY --from=builder /usr/local/cargo/bin/feature-flags /usr/local/bin/feature-flags WORKDIR /home/comm/app/feature-flags # Create a new user comm and use it to run subsequent commands RUN useradd -m comm USER comm ENV RUST_LOG=info -# For compatibility with the existing Terraform config -CMD ["feature-flags", "--http-port", "50051"] +CMD ["feature-flags"] diff --git a/services/terraform/remote/service_feature_flags.tf b/services/terraform/remote/service_feature_flags.tf index d5bbe9962..975cb3090 100644 --- a/services/terraform/remote/service_feature_flags.tf +++ b/services/terraform/remote/service_feature_flags.tf @@ -1,209 +1,209 @@ locals { - feature_flags_image_tag = "0.1" + feature_flags_image_tag = local.is_staging ? "latest" : "0.1.1" feature_flags_container_name = "feature-flags-server" - feature_flags_container_port = 50051 + feature_flags_container_port = 50055 feature_flags_server_image = "commapp/feature-flags:${local.feature_flags_image_tag}" feature_flags_domain_name = "feature-flags.${local.root_domain}" } # Task definition - defines container resources, ports, # environment variables, docker image etc. resource "aws_ecs_task_definition" "feature_flags" { family = "feature-flags-service-task-def" container_definitions = jsonencode([ { name = local.feature_flags_container_name image = local.feature_flags_server_image essential = true portMappings = [ { - name = "feature-flags-50051-http" + name = "feature-flags-http" containerPort = local.feature_flags_container_port protocol = "tcp" appProtocol = "http" } ] environment = [ { name = "RUST_LOG" value = "info" } ] logConfiguration = { "logDriver" = "awslogs" "options" = { "awslogs-create-group" = "true" "awslogs-group" = "/ecs/feature-flags-task-def" "awslogs-region" = "us-east-2" "awslogs-stream-prefix" = "ecs" } } } ]) task_role_arn = aws_iam_role.feature_flags_service.arn execution_role_arn = aws_iam_role.ecs_task_execution.arn network_mode = "awsvpc" cpu = "256" memory = "512" requires_compatibilities = ["EC2", "FARGATE"] # Set this to true if you want to keep old revisions # when this definition is changed skip_destroy = true } # ECS Service - defines task scaling, load balancer connection, # network configuration etc. resource "aws_ecs_service" "feature_flags" { name = "feature-flags-service" cluster = aws_ecs_cluster.comm_services.id launch_type = "FARGATE" task_definition = aws_ecs_task_definition.feature_flags.arn force_new_deployment = true desired_count = 1 # Allow external changes without Terraform plan difference # We can freely specify replica count in AWS Console lifecycle { ignore_changes = [desired_count] } load_balancer { target_group_arn = aws_lb_target_group.feature_flags_ecs.arn container_name = local.feature_flags_container_name container_port = local.feature_flags_container_port } network_configuration { assign_public_ip = true security_groups = [ aws_security_group.feature_flags.id, ] subnets = [ aws_subnet.public_a.id, aws_subnet.public_b.id, aws_subnet.public_c.id, ] } deployment_circuit_breaker { enable = true rollback = true } } # Running service instances are registered here # to be accessed by the load balancer resource "aws_lb_target_group" "feature_flags_ecs" { name = "feature-flags-ecs-tg" port = local.feature_flags_container_port protocol = "HTTP" vpc_id = aws_vpc.default.id # ECS Fargate requires target type set to IP target_type = "ip" health_check { enabled = true healthy_threshold = 2 unhealthy_threshold = 3 protocol = "HTTP" # The features endpoint should return HTTP 400 # if no platform, staff, code version is specified path = "/features" matcher = "200-499" } } # Security group to configure access to the service resource "aws_security_group" "feature_flags" { name = "feature-flags-service-sg" vpc_id = aws_vpc.default.id ingress { from_port = local.feature_flags_container_port to_port = local.feature_flags_container_port protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] description = "HTTP port" } # 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 } } # Load Balancer resource "aws_lb" "feature_flags" { load_balancer_type = "application" name = "feature-flags-service-lb" internal = false #security_groups = [aws_security_group.feature_flags.id] subnets = [ aws_subnet.public_a.id, aws_subnet.public_b.id, aws_subnet.public_c.id, ] } resource "aws_lb_listener" "feature_flags_https" { load_balancer_arn = aws_lb.feature_flags.arn port = "443" protocol = "HTTPS" ssl_policy = "ELBSecurityPolicy-2016-08" certificate_arn = data.aws_acm_certificate.feature_flags.arn default_action { type = "forward" forward { # ECS target group target_group { arn = aws_lb_target_group.feature_flags_ecs.arn weight = 10 } # Legacy EC2 Target dynamic "target_group" { for_each = data.aws_lb_target_group.feature_flags_legacy_ec2 content { arn = target_group.value["arn"] weight = 0 } } } } lifecycle { # Required only for existing resources to avoid plan difference ignore_changes = [default_action[0].forward[0].stickiness[0].duration] } } # SSL Certificate data "aws_acm_certificate" "feature_flags" { domain = local.feature_flags_domain_name statuses = ["ISSUED"] } # Legacy EC2 instance target data "aws_lb_target_group" "feature_flags_legacy_ec2" { # We don't have legacy EC2 services in staging count = local.is_staging ? 0 : 1 name = "feature-flags-service-tg" } # Required for Route53 DNS record output "feature_flags_load_balancer_dns_name" { value = aws_lb.feature_flags.dns_name }