Page MenuHomePhabricator

D9040.diff
No OneTemporary

D9040.diff

diff --git a/services/terraform/modules/shared/outputs.tf b/services/terraform/modules/shared/outputs.tf
--- a/services/terraform/modules/shared/outputs.tf
+++ b/services/terraform/modules/shared/outputs.tf
@@ -2,6 +2,7 @@
exported_dynamodb_tables = [
aws_dynamodb_table.feature-flags,
aws_dynamodb_table.backup-service-backup,
+ aws_dynamodb_table.reports-service-reports,
]
}
diff --git a/services/terraform/remote/aws_iam.tf b/services/terraform/remote/aws_iam.tf
--- a/services/terraform/remote/aws_iam.tf
+++ b/services/terraform/remote/aws_iam.tf
@@ -166,3 +166,31 @@
aws_iam_policy.manage_backup_ddb.arn
]
}
+
+# Reports Service IAM
+data "aws_iam_policy_document" "manage_reports_ddb" {
+ statement {
+ sid = "ReportsFullDDBAccess"
+ effect = "Allow"
+ actions = [
+ "dynamodb:*",
+ ]
+ resources = [
+ module.shared.dynamodb_tables["reports-service-reports"].arn
+ ]
+ }
+}
+resource "aws_iam_policy" "manage_reports_ddb" {
+ name = "reports-ddb-full-access"
+ policy = data.aws_iam_policy_document.manage_reports_ddb.json
+ description = "Allows full access to reports DynamoDB table"
+}
+resource "aws_iam_role" "reports_service" {
+ name = "reports-service-role"
+ assume_role_policy = data.aws_iam_policy_document.assume_role_ecs_ec2.json
+
+ managed_policy_arns = [
+ aws_iam_policy.allow_ecs_exec.arn,
+ aws_iam_policy.manage_reports_ddb.arn
+ ]
+}
diff --git a/services/terraform/remote/service_reports.tf b/services/terraform/remote/service_reports.tf
new file mode 100644
--- /dev/null
+++ b/services/terraform/remote/service_reports.tf
@@ -0,0 +1,196 @@
+locals {
+ reports_service_image_tag = local.is_staging ? "latest" : "0.1.0"
+ reports_service_container_name = "reports-service-server"
+ reports_service_server_image = "commapp/reports-server:${local.reports_service_image_tag}"
+ reports_service_container_http_port = 50056
+ reports_service_domain_name = "reports.${local.root_domain}"
+}
+
+resource "aws_secretsmanager_secret" "email_config" {
+ name_prefix = "email_config"
+ description = "E-mail configuration for the reports service"
+}
+resource "aws_secretsmanager_secret_version" "email_config" {
+ secret_id = aws_secretsmanager_secret.email_config.id
+ secret_string = jsonencode(local.secrets["emailConfig"])
+}
+
+resource "aws_ecs_task_definition" "reports_service" {
+ family = "reports-service-task-def"
+ container_definitions = jsonencode([
+ {
+ name = local.reports_service_container_name
+ image = local.reports_service_server_image
+ essential = true
+ portMappings = [
+ {
+ containerPort = local.reports_service_container_http_port
+ protocol = "tcp"
+ appProtocol = "http"
+ },
+ ]
+ environment = [
+ {
+ name = "RUST_LOG"
+ value = "info"
+ },
+ {
+ name = "PUBLIC_URL",
+ value = "https://${local.reports_service_domain_name}"
+ },
+ {
+ name = "BLOB_SERVICE_URL",
+ value = local.blob_local_url
+ # If this ever fails, we can fallback to blob public URL:
+ # "https://${local.blob_service_domain_name}"
+ },
+ ]
+ # Don't enable e-mails on staging.
+ secrets = local.is_staging ? [] : [
+ {
+ # This is exposed as an environment variable in the container
+ name = "EMAIL_CONFIG"
+ valueFrom = aws_secretsmanager_secret.email_config.arn
+ }
+ ]
+ logConfiguration = {
+ "logDriver" = "awslogs"
+ "options" = {
+ "awslogs-create-group" = "true"
+ "awslogs-group" = "/ecs/reports-service-task-def"
+ "awslogs-region" = "us-east-2"
+ "awslogs-stream-prefix" = "ecs"
+ }
+ }
+ }
+ ])
+ task_role_arn = aws_iam_role.reports_service.arn
+ execution_role_arn = aws_iam_role.ecs_task_execution.arn
+ network_mode = "bridge"
+ cpu = "256"
+ memory = "256"
+ requires_compatibilities = ["EC2"]
+
+ # Set this to true if you want to keep old revisions
+ # when this definition is changed
+ skip_destroy = false
+}
+
+resource "aws_ecs_service" "reports_service" {
+ name = "reports-service"
+ cluster = aws_ecs_cluster.comm_services.id
+ launch_type = "EC2"
+
+ task_definition = aws_ecs_task_definition.reports_service.arn
+ force_new_deployment = true
+
+ desired_count = 1
+ lifecycle {
+ ignore_changes = [desired_count]
+ }
+
+ service_connect_configuration {
+ # to be able to reach Blob service by DNS name
+ enabled = true
+ }
+
+ # HTTP
+ load_balancer {
+ target_group_arn = aws_lb_target_group.reports_service_http.arn
+ container_name = local.reports_service_container_name
+ container_port = local.reports_service_container_http_port
+ }
+
+ deployment_circuit_breaker {
+ enable = true
+ rollback = true
+ }
+
+ enable_execute_command = true
+ enable_ecs_managed_tags = true
+}
+
+# Security group to configure access to the service
+resource "aws_security_group" "reports_service" {
+ name = "reports-service-ecs-sg"
+ vpc_id = aws_vpc.default.id
+
+ ingress {
+ from_port = local.reports_service_container_http_port
+ to_port = local.reports_service_container_http_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
+ }
+}
+
+resource "aws_lb_target_group" "reports_service_http" {
+ name = "reports-service-ecs-http-tg"
+ port = local.reports_service_container_http_port
+ protocol = "HTTP"
+ vpc_id = aws_vpc.default.id
+
+ # ECS Fargate requires target type set to IP
+ target_type = "instance"
+
+ health_check {
+ enabled = true
+ healthy_threshold = 2
+ unhealthy_threshold = 3
+
+ protocol = "HTTP"
+ path = "/health"
+ matcher = "200-204"
+ }
+}
+
+# Load Balancer
+resource "aws_lb" "reports_service" {
+ load_balancer_type = "application"
+ name = "reports-service-lb"
+ internal = false
+ subnets = [
+ aws_subnet.public_a.id,
+ aws_subnet.public_b.id,
+ aws_subnet.public_c.id,
+ ]
+}
+
+resource "aws_lb_listener" "reports_service_https" {
+ load_balancer_arn = aws_lb.reports_service.arn
+ port = "443"
+ protocol = "HTTPS"
+ ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
+ certificate_arn = data.aws_acm_certificate.reports_service.arn
+
+ default_action {
+ type = "forward"
+ target_group_arn = aws_lb_target_group.reports_service_http.arn
+ }
+
+ lifecycle {
+ # Target group cannot be destroyed if it is used
+ replace_triggered_by = [aws_lb_target_group.reports_service_http]
+
+ # Required to avoid no-op plan differences
+ ignore_changes = [default_action[0].forward[0].stickiness[0].duration]
+ }
+}
+
+# SSL Certificate
+data "aws_acm_certificate" "reports_service" {
+ domain = local.reports_service_domain_name
+ statuses = ["ISSUED"]
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 24, 5:01 AM (20 h, 34 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2694474
Default Alt Text
D9040.diff (7 KB)

Event Timeline