diff --git a/tf/environments/dev/main.tf b/tf/environments/dev/main.tf index 95826431..809632b5 100644 --- a/tf/environments/dev/main.tf +++ b/tf/environments/dev/main.tf @@ -581,7 +581,7 @@ module "ooniapi_ooniprobe_deployer" { service_name = "ooniprobe" repo = "ooni/backend" - branch_name = "1237-check-in-to-th" + branch_name = "master" environment = local.environment trigger_path = "ooniapi/services/ooniprobe/**" buildspec_path = "ooniapi/services/ooniprobe/buildspec.yml" @@ -651,6 +651,59 @@ module "ooniapi_ooniprobe" { ) } +# Legacy ooniprobe service, used to serve older probes. Identified by the +# X-Protocol-Version header that specifies the anonymous credentials protocol +# version. +module "ooniapi_ooniprobe_legacy" { + source = "../../modules/ooniapi_service" + + # First run should be set on first run to bootstrap the task definition + # first_run = true + + task_memory = 256 + + vpc_id = module.network.vpc_id + + service_name = "ooniprobe-legacy" + default_docker_image_url = "ooni/api-ooniprobe:20260824-f2dac67a" + 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.ooniapi_cluster.cluster_id + + task_secrets = { + POSTGRESQL_URL = data.aws_ssm_parameter.oonipg_url.arn + JWT_ENCRYPTION_KEY = data.aws_ssm_parameter.jwt_secret_legacy.arn + PROMETHEUS_METRICS_PASSWORD = data.aws_ssm_parameter.prometheus_metrics_password.arn + CLICKHOUSE_URL = data.aws_ssm_parameter.clickhouse_ooniprobe_url.arn + ANONC_SECRET_KEY = data.aws_ssm_parameter.anonc_secret_key.arn + } + + task_environment = { + FASTPATH_URL = "http://fastpath.${local.environment}.ooni.io:8472" + FASTPATH_URLS = jsonencode([for h in local.fastpath_hosts : "http://${h}:8472"]) + FAILED_REPORTS_BUCKET = aws_s3_bucket.ooniprobe_failed_reports.bucket + COLLECTOR_ID = 3 # use a different one in prod + CONFIG_BUCKET = aws_s3_bucket.ooni_private_config_bucket.bucket + TOR_TARGETS = "tor_targets.json" + PSIPHON_CONFIG = "psiphon_config.json" + ANONC_MANIFEST_BUCKET = aws_s3_bucket.anoncred_manifests.bucket + ANONC_MANIFEST_FILE = "manifest.json" + } + + ooniapi_service_security_groups = [ + # module.ooniapi_cluster.web_security_group_id + ] + + use_autoscaling = false + service_desired_count = 1 + + tags = merge( + local.tags, + { Name = "ooni-tier0-ooniprobe-legacy" } + ) +} + #### OONI Backend proxy service module "ooniapi_reverseproxy_deployer" { @@ -1301,6 +1354,7 @@ module "ooniapi_frontend" { ooniapi_oonirun_target_group_arn = module.ooniapi_oonirun.alb_target_group_id ooniapi_ooniauth_target_group_arn = module.ooniapi_ooniauth.alb_target_group_id ooniapi_ooniprobe_target_group_arn = module.ooniapi_ooniprobe.alb_target_group_id + ooniapi_ooniprobe_legacy_target_group_arn = module.ooniapi_ooniprobe_legacy.alb_target_group_id ooniapi_oonifindings_target_group_arn = module.ooniapi_oonifindings.alb_target_group_id ooniapi_oonimeasurements_target_group_arn = module.ooniapi_oonimeasurements.alb_target_group_id ooniapi_testlists_target_group_arn = module.ooniapi_testlists.alb_target_group_id diff --git a/tf/environments/prod/main.tf b/tf/environments/prod/main.tf index b6980c4b..ab6438a7 100644 --- a/tf/environments/prod/main.tf +++ b/tf/environments/prod/main.tf @@ -966,6 +966,59 @@ module "ooniapi_ooniprobe" { ) } +# Legacy ooniprobe service, used to serve older probes. Identified by the +# X-Protocol-Version header that specifies the anonymous credentials protocol +# version. +module "ooniapi_ooniprobe_legacy" { + source = "../../modules/ooniapi_service" + + # First run should be set on first run to bootstrap the task definition + first_run = true + + vpc_id = module.network.vpc_id + + service_name = "ooniprobe-legacy" + default_docker_image_url = "ooni/api-ooniprobe:20260824-f2dac67a" + 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.ooniapi_cluster.cluster_id + task_memory = 1024 + + task_secrets = { + POSTGRESQL_URL = data.aws_ssm_parameter.oonipg_url.arn + JWT_ENCRYPTION_KEY = data.aws_ssm_parameter.jwt_secret.arn + PROMETHEUS_METRICS_PASSWORD = data.aws_ssm_parameter.prometheus_metrics_password.arn + CLICKHOUSE_URL = data.aws_ssm_parameter.clickhouse_write_url.arn + ANONC_SECRET_KEY = data.aws_ssm_parameter.anonc_secret_key.arn + } + + task_environment = { + # hardcoded IP for fastpath2.prod.prod.ooni.io + FASTPATH_URL = "http://10.0.0.32:8472" + FASTPATH_URLS = jsonencode([for h in local.fastpath_hosts : "http://${h}:8472"]) + FAILED_REPORTS_BUCKET = aws_s3_bucket.ooniprobe_failed_reports.bucket + COLLECTOR_ID = 4 # be sure this is different from dev + CONFIG_BUCKET = aws_s3_bucket.ooni_private_config_bucket.bucket + TOR_TARGETS = "tor_targets.json" + PSIPHON_CONFIG = "psiphon_config.json" + ANONC_MANIFEST_BUCKET = aws_s3_bucket.anoncred_manifests.bucket + ANONC_MANIFEST_FILE = "manifest.json" + } + + ooniapi_service_security_groups = [ + module.ooniapi_cluster.web_security_group_id + ] + + use_autoscaling = false + service_desired_count = 1 + + tags = merge( + local.tags, + { Name = "ooni-tier0-ooniprobe-legacy" } + ) +} + ### Fastpath module "ooni_fastpath" { source = "../../modules/ooni_fastpath" @@ -1534,6 +1587,7 @@ module "ooniapi_frontend" { ooniapi_oonirun_target_group_arn = module.ooniapi_oonirun.alb_target_group_id ooniapi_ooniauth_target_group_arn = module.ooniapi_ooniauth.alb_target_group_id ooniapi_ooniprobe_target_group_arn = module.ooniapi_ooniprobe.alb_target_group_id + ooniapi_ooniprobe_legacy_target_group_arn = module.ooniapi_ooniprobe_legacy.alb_target_group_id ooniapi_oonifindings_target_group_arn = module.ooniapi_oonifindings.alb_target_group_id ooniapi_oonimeasurements_target_group_arn = module.ooniapi_oonimeasurements.alb_target_group_id ooniapi_testlists_target_group_arn = module.ooniapi_testlists.alb_target_group_id diff --git a/tf/modules/ooniapi_frontend/main.tf b/tf/modules/ooniapi_frontend/main.tf index d6034f2e..2e1bee8e 100644 --- a/tf/modules/ooniapi_frontend/main.tf +++ b/tf/modules/ooniapi_frontend/main.tf @@ -377,22 +377,79 @@ resource "aws_lb_listener_rule" "ooniapi_ooniprobe_rule_2" { } } -resource "aws_lb_listener_rule" "ooniapi_ooniprobe_rule_3" { +resource "aws_lb_listener_rule" "ooniapi_ooniprobe_rule_3_legacy_version" { listener_arn = aws_alb_listener.ooniapi_listener_https.arn priority = 122 + action { + type = "forward" + target_group_arn = var.ooniapi_ooniprobe_legacy_target_group_arn + } + + condition { + path_pattern { + values = [ + "/api/v1/manifest*", + "/api/v1/submit_measurement*", + "/api/v1/sign_credential*" + ] + } + } + + condition { + http_header { + http_header_name = "X-Protocol-Version" + values = ["0.1.0"] + } + } +} + +resource "aws_lb_listener_rule" "ooniapi_ooniprobe_rule_3_current_version" { + listener_arn = aws_alb_listener.ooniapi_listener_https.arn + priority = 124 + action { type = "forward" target_group_arn = var.ooniapi_ooniprobe_target_group_arn } - # anonymous credentials condition { path_pattern { values = [ "/api/v1/manifest*", - "/api/v1/sign_credential*", - "/api/v1/submit_measurement*" + "/api/v1/submit_measurement*", + "/api/v1/sign_credential*" + ] + } + } + + # matches any value, but only when the header is present + condition { + http_header { + http_header_name = "X-Protocol-Version" + values = ["*"] + } + } +} + +resource "aws_lb_listener_rule" "ooniapi_ooniprobe_rule_3_no_version" { + listener_arn = aws_alb_listener.ooniapi_listener_https.arn + priority = 126 + + action { + type = "forward" + target_group_arn = var.ooniapi_ooniprobe_legacy_target_group_arn + } + + # No X-Protocol-Version header at all: rules 122/124 above already + # matched every request that does carry the header, so anything left + # here is header-less and should go to the legacy service. + condition { + path_pattern { + values = [ + "/api/v1/manifest*", + "/api/v1/submit_measurement*", + "/api/v1/sign_credential*" ] } } diff --git a/tf/modules/ooniapi_frontend/variables.tf b/tf/modules/ooniapi_frontend/variables.tf index d92c39e3..614056e6 100644 --- a/tf/modules/ooniapi_frontend/variables.tf +++ b/tf/modules/ooniapi_frontend/variables.tf @@ -28,6 +28,10 @@ variable "ooniapi_ooniprobe_target_group_arn" { description = "arn for the target group of the ooniprobe service" } +variable "ooniapi_ooniprobe_legacy_target_group_arn" { + description = "arn for the target group of the legacy ooniprobe service" +} + variable "ooniapi_oonifindings_target_group_arn" { description = "arn for the target group of the oonifindings service" } diff --git a/tf/modules/ooniapi_service/main.tf b/tf/modules/ooniapi_service/main.tf index 84e9f38f..94bebfd8 100644 --- a/tf/modules/ooniapi_service/main.tf +++ b/tf/modules/ooniapi_service/main.tf @@ -126,6 +126,9 @@ resource "aws_ecs_service" "ooniapi_service" { lifecycle { create_before_destroy = true + # fixes an issue when AWS changes the capacity provider + # on its own, terraform has no record of that on its internal state + ignore_changes = [capacity_provider_strategy] } force_new_deployment = true