From 6cc4b4e88f3e2ae88c2e63bd82a1b38eae6ce9fb Mon Sep 17 00:00:00 2001 From: Julian Scott Date: Fri, 18 Sep 2026 14:02:18 -0700 Subject: [PATCH 1/8] Updates for DPC adoption --- terraform/modules/service/data.tf | 4 +++ terraform/modules/service/iam.tf | 1 + terraform/modules/service/main.tf | 43 ++++++++++++++++--------- terraform/modules/service/variables.tf | 44 ++++++-------------------- 4 files changed, 42 insertions(+), 50 deletions(-) diff --git a/terraform/modules/service/data.tf b/terraform/modules/service/data.tf index fdb1ad5b..776d0985 100644 --- a/terraform/modules/service/data.tf +++ b/terraform/modules/service/data.tf @@ -30,3 +30,7 @@ data "aws_ssm_parameter" "mtls_image_tag" { count = var.enable_mtls_sidecar ? 1 : 0 name = "/cdap/${local.cdap_ssm_env}/nonsensitive/mtls-sidecar/image-tag" } + +data "aws_service_discovery_http_namespace" "service_discovery_namespace" { + name = "${var.platform.env}.${var.platform.app}.cmscloud.local" +} diff --git a/terraform/modules/service/iam.tf b/terraform/modules/service/iam.tf index 017be947..37279845 100644 --- a/terraform/modules/service/iam.tf +++ b/terraform/modules/service/iam.tf @@ -163,6 +163,7 @@ data "aws_iam_policy_document" "service_connect" { "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:UpdateSecret", + "secretsmanager:UpdateSecretVersionStage", "secretsmanager:DeleteSecret", "secretsmanager:PutSecretValue", "secretsmanager:TagResource", diff --git a/terraform/modules/service/main.tf b/terraform/modules/service/main.tf index 869127ae..3c4994ea 100644 --- a/terraform/modules/service/main.tf +++ b/terraform/modules/service/main.tf @@ -433,27 +433,39 @@ resource "aws_ecs_service" "this" { } } - dynamic "service_connect_configuration" { - for_each = var.enable_ecs_service_connect ? [1] : [] - content { - enabled = true - namespace = var.service_connect_namespace_arn + service_connect_configuration { + enabled = (length(var.service_connect) > 0) ? true : false + namespace = data.aws_service_discovery_http_namespace.service_discovery_namespace.arn - service { - discovery_name = local.service_name - port_name = local.sc_port_name + log_configuration { + log_driver = "awslogs" + options = { + "awslogs-group" = aws_cloudwatch_log_group.app.name + "awslogs-stream-prefix" = "service-connect" + "awslogs-region" = "us-east-1" + } + } + + access_log_configuration { + format = "TEXT" + include_query_parameters = "ENABLED" + } + + dynamic "service" { + for_each = var.service_connect + + content { + discovery_name = service.value.discovery_name + port_name = service.value.port_name client_alias { - port = coalesce( - var.service_connect_client_port, - local.sc_port_name != null ? try(local.port_map[local.sc_port_name], null) : null - ) - dns_name = local.service_name + dns_name = service.value.dns_name + port = service.value.port } tls { - kms_key = var.platform.kms_alias_primary.target_key_arn - role_arn = aws_iam_role.service_connect[0].arn + kms_key = module.platform.kms_alias_primary.arn + role_arn = aws_iam_role.service_connect.arn issuer_cert_authority { aws_pca_authority_arn = one(data.aws_ram_resource_share.pace_ca.resource_arns) @@ -462,6 +474,7 @@ resource "aws_ecs_service" "this" { } } } + deployment_minimum_healthy_percent = var.deployment_minimum_healthy_percent deployment_maximum_percent = var.deployment_maximum_percent health_check_grace_period_seconds = var.health_check_grace_period_seconds diff --git a/terraform/modules/service/variables.tf b/terraform/modules/service/variables.tf index 25361b81..79890c39 100644 --- a/terraform/modules/service/variables.tf +++ b/terraform/modules/service/variables.tf @@ -119,41 +119,16 @@ variable "alb_security_group_id" { # ------------------------------------------------------- # ECS Service Connect (optional) # ------------------------------------------------------- -variable "enable_ecs_service_connect" { - description = "Enables ECS Service Connect so other services in the namespace can reach this one." - type = bool - default = false -} - -variable "service_connect_namespace_arn" { - type = string - default = null - description = <<-EOT - ARN of the Cloud Map HTTP namespace to use for ECS Service Connect. - When null, Service Connect will not be configured for this service. - EOT -} - -variable "service_connect_port" { - type = number - default = null - description = "Optional. Defaults to the first containerPort in port_mappings. Override this for port remapping (e.g. expose on :80 while container listens on :8080)." -} -variable "service_connect_port_name" { - type = string - default = null - description = "Optional. Defaults to the first named port in port_mappings. Name of the port mapping to use for Service Connect." -} - -variable "service_connect_client_port" { - type = number - default = null - description = <<-EOT - Override the port clients use to call this service via Service Connect. - Defaults to the containerPort of the named port mapping. - Use this for port remapping (e.g. container listens on 8080, clients call on 80 for easy calls by name without port). - EOT +variable "service_connect" { + default = [] + description = "List of service connect discovery names and ports." + type = list(object({ + discovery_name = string + dns_name = string + port = number + port_name = string + })) } variable "deployment_circuit_breaker" { @@ -264,7 +239,6 @@ variable "load_balancers" { default = null } - #-------------------- # ALB Connection #-------------------- From a935f50d7242e475b0c5e823f805780c668f53bc Mon Sep 17 00:00:00 2001 From: Julian Scott Date: Tue, 22 Sep 2026 09:58:15 -0700 Subject: [PATCH 2/8] Updates --- terraform/modules/service/iam.tf | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/terraform/modules/service/iam.tf b/terraform/modules/service/iam.tf index 37279845..82387404 100644 --- a/terraform/modules/service/iam.tf +++ b/terraform/modules/service/iam.tf @@ -26,7 +26,6 @@ resource "aws_iam_role_policy" "execution" { policy = data.aws_iam_policy_document.execution[0].json } - data "aws_iam_policy_document" "execution" { count = var.execution_role_arn != null ? 0 : 1 statement { @@ -77,7 +76,7 @@ data "aws_iam_policy_document" "execution" { } dynamic "statement" { - for_each = var.enable_ecs_service_connect ? [1] : [] + for_each = (length(var.service_connect) > 0) ? [1] : [] content { sid = "AllowPassServiceConnectRole" actions = ["iam:PassRole"] @@ -112,14 +111,14 @@ resource "aws_iam_role" "service_connect" { } resource "aws_iam_policy" "service_connect" { - count = var.enable_ecs_service_connect ? 1 : 0 + count = (length(var.service_connect) > 0) ? 1 : 0 name = "${local.service_name_full}-service-connect" description = "Base permissions for ECS Service Connect TLS lifecycle" policy = data.aws_iam_policy_document.service_connect.json } resource "aws_iam_role_policy_attachment" "service_connect" { - count = var.enable_ecs_service_connect ? 1 : 0 + count = (length(var.service_connect) > 0) ? 1 : 0 role = aws_iam_role.service_connect[0].name policy_arn = aws_iam_policy.service_connect[0].arn } @@ -137,7 +136,7 @@ data "aws_iam_policy_document" "service_connect" { } dynamic "statement" { - for_each = var.enable_ecs_service_connect ? [1] : [] + for_each = (length(var.service_connect) > 0) ? [1] : [] content { sid = "AllowCertManagement" actions = [ From c87ea9565495eeafbdf37e0d60b8ab961fdd11ba Mon Sep 17 00:00:00 2001 From: Julian Scott Date: Tue, 22 Sep 2026 10:11:16 -0700 Subject: [PATCH 3/8] Updates --- terraform/modules/service/iam.tf | 2 +- terraform/modules/service/outputs.tf | 27 +-------------------------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/terraform/modules/service/iam.tf b/terraform/modules/service/iam.tf index 82387404..fc355358 100644 --- a/terraform/modules/service/iam.tf +++ b/terraform/modules/service/iam.tf @@ -90,7 +90,7 @@ data "aws_iam_policy_document" "execution" { #--------------------------- resource "aws_iam_role" "service_connect" { - count = var.enable_ecs_service_connect ? 1 : 0 + count = (length(var.service_connect) > 0) ? 1 : 0 name = "${local.service_name_full}-service-connect" assume_role_policy = jsonencode({ diff --git a/terraform/modules/service/outputs.tf b/terraform/modules/service/outputs.tf index 254a48b0..02d71cf4 100644 --- a/terraform/modules/service/outputs.tf +++ b/terraform/modules/service/outputs.tf @@ -35,7 +35,7 @@ output "listener_rule_arn" { output "service_connect_role_arn" { description = "ARN of the Service Connect IAM role (if Service Connect is enabled)." - value = var.enable_ecs_service_connect ? aws_iam_role.service_connect[0].arn : null + value = (length(var.service_connect) > 0) ? aws_iam_role.service_connect[0].arn : null } output "task_security_group_id" { @@ -47,28 +47,3 @@ output "task_role_arn" { description = "ARN of the ECS task role (module-managed or externally provided)." value = aws_iam_role.task.arn } - -output "service_connect_port" { - description = "Port clients should use when calling this service via Service Connect." - value = var.enable_ecs_service_connect ? coalesce( - var.service_connect_client_port, - local.sc_port_name != null ? try(local.port_map[local.sc_port_name], null) : null - ) : null -} - -output "service_connect_name" { - description = "Short DNS name for this service within the Service Connect namespace. Other services call this service at http://:/." - value = var.enable_ecs_service_connect ? local.service_name : null -} - -output "service_connect_endpoint" { - description = "Full Service Connect endpoint for this service (e.g. http://api:8080). Null if Service Connect is not enabled." - value = var.enable_ecs_service_connect ? format( - "http://%s:%d", - local.service_name, - coalesce( - var.service_connect_client_port, - local.sc_port_name != null ? try(local.port_map[local.sc_port_name], null) : null - ) - ) : null -} From 196d7bd55323745a867abf56dc4a2738a790ab6e Mon Sep 17 00:00:00 2001 From: Julian Scott Date: Tue, 22 Sep 2026 10:30:16 -0700 Subject: [PATCH 4/8] Updates --- terraform/modules/service/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/modules/service/main.tf b/terraform/modules/service/main.tf index 3c4994ea..fa3aede8 100644 --- a/terraform/modules/service/main.tf +++ b/terraform/modules/service/main.tf @@ -72,7 +72,7 @@ locals { sc_port_name = try( coalesce( - var.service_connect_port_name, + var.service_connect[0].port_name, local.enable_mtls_sidecar ? "proxy" : try( [for pm in coalesce(var.port_mappings, []) : pm.name if pm.name != null][0], null From f1369e1ac7e5766e13a08e71bd1b67d817652eac Mon Sep 17 00:00:00 2001 From: Julian Scott Date: Tue, 22 Sep 2026 11:06:47 -0700 Subject: [PATCH 5/8] Updates --- terraform/modules/service/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/terraform/modules/service/main.tf b/terraform/modules/service/main.tf index fa3aede8..b373a311 100644 --- a/terraform/modules/service/main.tf +++ b/terraform/modules/service/main.tf @@ -464,8 +464,8 @@ resource "aws_ecs_service" "this" { } tls { - kms_key = module.platform.kms_alias_primary.arn - role_arn = aws_iam_role.service_connect.arn + kms_key = var.platform.kms_alias_primary.arn + role_arn = aws_iam_role.service_connect[0].arn issuer_cert_authority { aws_pca_authority_arn = one(data.aws_ram_resource_share.pace_ca.resource_arns) From f2db8aafd3bf137b1bda94fb61683dd071a8e0e4 Mon Sep 17 00:00:00 2001 From: Julian Scott Date: Tue, 22 Sep 2026 11:11:13 -0700 Subject: [PATCH 6/8] Updates --- terraform/modules/service/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/modules/service/main.tf b/terraform/modules/service/main.tf index b373a311..ffc3fb6d 100644 --- a/terraform/modules/service/main.tf +++ b/terraform/modules/service/main.tf @@ -464,7 +464,7 @@ resource "aws_ecs_service" "this" { } tls { - kms_key = var.platform.kms_alias_primary.arn + kms_key = var.platform.kms_alias_primary["target_key_arn"] role_arn = aws_iam_role.service_connect[0].arn issuer_cert_authority { From 0f5eafd17aae55eb81c1b8f8fc3d2a7e6a47f4c9 Mon Sep 17 00:00:00 2001 From: Julian Scott Date: Fri, 25 Sep 2026 11:16:16 -0700 Subject: [PATCH 7/8] DD env updates --- terraform/modules/service/main.tf | 38 ++++++++++++++------------ terraform/modules/service/variables.tf | 9 ++++++ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/terraform/modules/service/main.tf b/terraform/modules/service/main.tf index ffc3fb6d..c35aca03 100644 --- a/terraform/modules/service/main.tf +++ b/terraform/modules/service/main.tf @@ -248,23 +248,27 @@ locals { } ] - environment = [ - { name = "ECS_FARGATE", value = "true" }, - { name = "DD_APM_ENABLED", value = "true" }, - { name = "DD_APM_NON_LOCAL_TRAFFIC", value = "true" }, - { name = "DD_APM_RECEIVER_PORT", value = "8126" }, - { name = "DD_APM_TELEMETRY_ENABLED", value = "false" }, - { name = "DD_DATA_STREAMS_ENABLED", value = "false" }, - { name = "DD_DOGSTATSD_NON_LOCAL_TRAFFIC", value = "true" }, - { name = "DD_DOGSTATSD_PORT", value = "8125" }, # Default - { name = "DD_ECS_TASK_COLLECTION_ENABLED", value = "true" }, - { name = "DD_ENV", value = var.platform.env }, - { name = "DD_LOGS_ENABLED", value = "false" }, # DD logging is currently not approved - { name = "DD_PROCESS_AGENT_ENABLED", value = "true" }, - { name = "DD_SERVICE", value = local.service_name }, - { name = "DD_SITE", value = "ddog-gov.com" }, - { name = "DD_TAGS", value = "application:${var.platform.app}, service:${local.service_name}" }, - ] + environment = concat( + [ + { name = "ECS_FARGATE", value = "true" }, + { name = "DD_APM_ENABLED", value = "true" }, + { name = "DD_APM_NON_LOCAL_TRAFFIC", value = "true" }, + { name = "DD_APM_RECEIVER_PORT", value = "8126" }, + { name = "DD_APM_TELEMETRY_ENABLED", value = "false" }, + { name = "DD_DATA_STREAMS_ENABLED", value = "false" }, + { name = "DD_DOGSTATSD_NON_LOCAL_TRAFFIC", value = "true" }, + { name = "DD_DOGSTATSD_PORT", value = "8125" }, # Default + { name = "DD_ECS_TASK_COLLECTION_ENABLED", value = "true" }, + { name = "DD_ENV", value = var.platform.env }, + { name = "DD_LOGS_ENABLED", value = "false" }, # DD logging is currently not approved + { name = "DD_PROCESS_AGENT_ENABLED", value = "true" }, + { name = "DD_SERVICE", value = local.service_name }, + { name = "DD_SITE", value = "ddog-gov.com" }, + { name = "DD_TAGS", value = "application:${var.platform.app}, service:${local.service_name}" }, + ], + var.additional_dd_environment + ) + secrets = [{ name = "DD_API_KEY", valueFrom = data.aws_ssm_parameter.datadog_api_key.name }] } } diff --git a/terraform/modules/service/variables.tf b/terraform/modules/service/variables.tf index 79890c39..737103b4 100644 --- a/terraform/modules/service/variables.tf +++ b/terraform/modules/service/variables.tf @@ -488,3 +488,12 @@ variable "dd_version" { type = string default = "1.0.0" } + +variable "additional_dd_environment" { + default = [] + description = "A list of additional environment variables to append to the default Datadog environment." + type = list(object({ + name = string, + value = string + })) +} From 4f4520fa3fff0bb53880b3c426df952a3e989aaf Mon Sep 17 00:00:00 2001 From: Julian Scott Date: Wed, 30 Sep 2026 08:31:16 -0700 Subject: [PATCH 8/8] Updates --- terraform/modules/service/iam.tf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/terraform/modules/service/iam.tf b/terraform/modules/service/iam.tf index fc355358..556a427c 100644 --- a/terraform/modules/service/iam.tf +++ b/terraform/modules/service/iam.tf @@ -284,7 +284,6 @@ resource "aws_iam_policy" "ecs_exec" { policy = data.aws_iam_policy_document.ecs_exec.json } - data "aws_iam_policy_document" "ecs_exec" { statement { sid = "AllowECSExec" @@ -297,3 +296,9 @@ data "aws_iam_policy_document" "ecs_exec" { resources = ["*"] } } + +resource "aws_iam_role_policy_attachment" "ecs_exec" { + count = var.enable_execute_command ? 1 : 0 + role = aws_iam_role.task.name + policy_arn = aws_iam_policy.ecs_exec[0].arn +}