From b138888fd1a59a2c0bcd7042e611030559b1c688 Mon Sep 17 00:00:00 2001 From: DecFox Date: Tue, 19 Mar 2024 16:49:24 +0530 Subject: [PATCH] feat: add oonith service Add oonith_service and oonith_service_deployer to deploy the oonihelperd service from ooni/backend This is the final step in https://github.com/ooni/devops/issues/29 --- tf/environments/dev/main.tf | 42 ++- tf/modules/oonith_service/main.tf | 222 ++++++++++++++ tf/modules/oonith_service/outputs.tf | 15 + .../templates/profile_policy.json | 51 ++++ tf/modules/oonith_service/variables.tf | 72 +++++ tf/modules/oonith_service_deployer/main.tf | 273 ++++++++++++++++++ tf/modules/oonith_service_deployer/outputs.tf | 0 .../templates/codepipeline_policy.json | 162 +++++++++++ .../oonith_service_deployer/variables.tf | 36 +++ 9 files changed, 872 insertions(+), 1 deletion(-) create mode 100644 tf/modules/oonith_service/main.tf create mode 100644 tf/modules/oonith_service/outputs.tf create mode 100644 tf/modules/oonith_service/templates/profile_policy.json create mode 100644 tf/modules/oonith_service/variables.tf create mode 100644 tf/modules/oonith_service_deployer/main.tf create mode 100644 tf/modules/oonith_service_deployer/outputs.tf create mode 100644 tf/modules/oonith_service_deployer/templates/codepipeline_policy.json create mode 100644 tf/modules/oonith_service_deployer/variables.tf diff --git a/tf/environments/dev/main.tf b/tf/environments/dev/main.tf index c73e0f4c..b0a79029 100644 --- a/tf/environments/dev/main.tf +++ b/tf/environments/dev/main.tf @@ -235,7 +235,7 @@ resource "aws_codestarconnections_connection" "ooniapi" { } resource "aws_codestarconnections_connection" "oonith" { - name = "oonith" + name = "oonith" provider_type = "GitHub" depends_on = [module.adm_iam_roles] @@ -434,3 +434,43 @@ module "ooniapi_frontend" { { Name = "ooni-tier0-api-frontend" } ) } + +#### OONI oohelperd service + +module "oonith_oohelperd_deployer" { + source = "../../modules/oonith_service_deployer" + + service_name = "oohelperd" + repo = "ooni/backend" + branch_name = "master" + buildspec_path = "oonith/buildspec.yml" + codestar_connection_arn = aws_codestarconnections_connection.oonith.arn + + codepipeline_bucket = aws_s3_bucket.oonith_codepipeline_bucket.bucket + + ecs_service_name = module.oonith_oohelperd.ecs_service_name + ecs_cluster_name = module.oonith_cluster.cluster_name +} + +module "oonith_oohelperd" { + source = "../../modules/oonith_service" + + vpc_id = module.network.vpc_id + subnet_ids = module.network.vpc_subnet[*].id + + service_name = "oonhelperd" + default_docker_image_url = "ooni/oonith-oohelperd:latest" + stage = local.environment + dns_zone_ooni_io = local.dns_zone_ooni_io + key_name = module.adm_iam_roles.oonidevops_key_name + ecs_cluster_id = module.oonith_cluster.cluster_id + + oonith_service_security_groups = [ + module.oonith_cluster.web_security_group_id + ] + + tags = merge( + local.tags, + { Name = "ooni-tier0-oohelperd" } + ) +} diff --git a/tf/modules/oonith_service/main.tf b/tf/modules/oonith_service/main.tf new file mode 100644 index 00000000..d4d1c80d --- /dev/null +++ b/tf/modules/oonith_service/main.tf @@ -0,0 +1,222 @@ +locals { + name = "oonith-service-${var.service_name}" +} + +resource "aws_iam_role" "oonith_service_task" { + name = "${local.name}-task-role" + + tags = var.tags + + assume_role_policy = < { + name = dvo.resource_record_name + record = dvo.resource_record_value + type = dvo.resource_record_type + } + } + + allow_overwrite = true + name = each.value.name + records = [each.value.record] + ttl = 60 + type = each.value.type + zone_id = var.dns_zone_ooni_io +} + +resource "aws_acm_certificate_validation" "oonith_service" { + certificate_arn = aws_acm_certificate.oonith_service.arn + validation_record_fqdns = [for record in aws_route53_record.oonith_service_validation : record.fqdn] + depends_on = [ + aws_route53_record.oonith_service + ] +} diff --git a/tf/modules/oonith_service/outputs.tf b/tf/modules/oonith_service/outputs.tf new file mode 100644 index 00000000..bd538c49 --- /dev/null +++ b/tf/modules/oonith_service/outputs.tf @@ -0,0 +1,15 @@ +output "ooni_io_fqdn" { + value = aws_route53_record.oonith_service.name +} + +output "dns_name" { + value = aws_alb.oonith_service.dns_name +} + +output "ecs_service_name" { + value = aws_ecs_service.oonith_service.name +} + +output "alb_target_group_id" { + value = aws_alb_target_group.oonith_service_mapped.id +} diff --git a/tf/modules/oonith_service/templates/profile_policy.json b/tf/modules/oonith_service/templates/profile_policy.json new file mode 100644 index 00000000..5857ee55 --- /dev/null +++ b/tf/modules/oonith_service/templates/profile_policy.json @@ -0,0 +1,51 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ecsInstanceRole", + "Effect": "Allow", + "Action": [ + "ecs:DeregisterContainerInstance", + "ecs:DiscoverPollEndpoint", + "ecs:Poll", + "ecs:RegisterContainerInstance", + "ecs:Submit*", + "ecs:StartTelemetrySession" + ], + "Resource": ["*"] + }, + { + "Sid": "CloudWatchLogsFullAccess", + "Effect": "Allow", + "Action": ["logs:*", "cloudwatch:GenerateQuery"], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "secretsmanager:GetResourcePolicy", + "secretsmanager:GetSecretValue", + "secretsmanager:DescribeSecret", + "secretsmanager:ListSecretVersionIds" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": "secretsmanager:ListSecrets", + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "ec2:Describe*", + "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", + "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:Describe*", + "elasticloadbalancing:RegisterInstancesWithLoadBalancer", + "elasticloadbalancing:RegisterTargets" + ], + "Resource": "*" + } + ] +} diff --git a/tf/modules/oonith_service/variables.tf b/tf/modules/oonith_service/variables.tf new file mode 100644 index 00000000..6eb49bb9 --- /dev/null +++ b/tf/modules/oonith_service/variables.tf @@ -0,0 +1,72 @@ +variable "aws_region" { + description = "The AWS region to create things in." + default = "eu-central-1" +} + +variable "key_name" { + description = "Name of AWS key pair" +} + +variable "service_name" { + description = "short service name. will become the first part of the fqdn eg. .prod.ooni.io" +} + +variable "stage" { + default = "one of dev, stage, test, prod" +} + +variable "vpc_id" { + description = "the id of the VPC to deploy the instance into" +} + +variable "subnet_ids" { + description = "the ids of the subnet of the subnets to deploy the instance into" +} + +variable "tags" { + description = "tags to apply to the resources" + default = {} + type = map(string) +} + +variable "service_desired_count" { + description = "Desired numbers of instances in the ecs service" + default = 2 +} + +variable "task_cpu" { + default = 256 + description = "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size" +} + +variable "task_memory" { + default = 512 + description = "https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size" +} + +variable "dns_zone_ooni_io" { + description = "id of the DNS zone for ooni_io" +} + +variable "default_docker_image_url" { + description = "the url to the default docker image unless there is one already defined in the task definition" +} + +variable "ecs_cluster_id" { + description = "id of the cluster to deploy into" +} + +variable "task_secrets" { + default = {} + type = map(string) +} + +variable "task_environment" { + default = {} + type = map(string) +} + +variable "ooniapi_service_security_groups" { + description = "the shared web security group from the ecs cluster" + type = list(string) +} diff --git a/tf/modules/oonith_service_deployer/main.tf b/tf/modules/oonith_service_deployer/main.tf new file mode 100644 index 00000000..44a11b0d --- /dev/null +++ b/tf/modules/oonith_service_deployer/main.tf @@ -0,0 +1,273 @@ + +## CodeBuild and CodePipeline for OONI TH Services + +data "aws_caller_identity" "current" {} + +locals { + account_id = data.aws_caller_identity.current.account_id +} + +resource "aws_iam_policy" "codebuild" { + description = "Policy used in trust relationship with CodeBuild" + name = "codebuild-${var.service_name}-${var.aws_region}" + path = "/service-role/" + + policy = <