From 7513538024e0c66fb300d68180882499a4cf797c Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Wed, 29 Oct 2025 16:44:04 -0400 Subject: [PATCH 1/9] use init config and volume containers for rofs --- modules/ecs_fargate/datadog.tf | 96 +++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/modules/ecs_fargate/datadog.tf b/modules/ecs_fargate/datadog.tf index d22fda2..4b02173 100644 --- a/modules/ecs_fargate/datadog.tf +++ b/modules/ecs_fargate/datadog.tf @@ -77,6 +77,32 @@ locals { } ] : [] + dd_agent_mount = concat( + local.apm_dsd_mount, + [ + { + containerPath = "/etc/datadog-agent" + sourceVolume = "agent-config" + readOnly = false + }, + { + containerPath = "/tmp" + sourceVolume = "agent-tmp" + readOnly = false + }, + { + containerPath = "/var/log/datadog" + sourceVolume = "agent-logs" + readOnly = false + }, + { + containerPath = "/opt/datadog-agent/run" + sourceVolume = "agent-run" + readOnly = false + } + ] + ) + apm_socket_var = local.is_apm_socket_mount ? [ { name = "DD_TRACE_AGENT_URL" @@ -223,6 +249,21 @@ locals { ) ] + rofs_volumes = [ + { + name = "agent-config" + }, + { + name = "agent-tmp" + }, + { + name = "agent-logs" + }, + { + name = "agent-run" + } + ] + # Volume configuration for task apm_dsd_volume = local.is_apm_dsd_volume ? [ { @@ -238,6 +279,7 @@ locals { modified_volumes = concat( [for k, v in coalesce(var.volumes, []) : v], + local.rofs_volumes, local.apm_dsd_volume, local.cws_volume, ) @@ -310,6 +352,44 @@ locals { # Datadog Agent container definition dd_agent_container = [ + { + cpu = 0 + memory = 128 + name = "init-volume" + image = "${var.dd_registry}:${var.dd_image_version}" + essential = false + readOnlyRootFilesystem = true + command = ["/bin/sh", "-c", "cp -vnR /etc/datadog-agent/* /agent-config/ && exit 0"] + mountPoints = [ + { + sourceVolume = "agent-config" + containerPath = "/agent-config" + readOnly = false + } + ] + }, + { + cpu = 0 + memory = 128 + name = "init-config" + image = "${var.dd_registry}:${var.dd_image_version}" + essential = false + readOnlyRootFilesystem = true + command = ["/bin/sh", "-c", "for script in $(find /etc/cont-init.d/ -type f -name '*.sh' | sort) ; do bash $script ; done"] + dependsOn = [ + { + condition = "SUCCESS" + containerName = "init-volume" + } + ] + mountPoints = [ + { + sourceVolume = "agent-config" + containerPath = "/etc/datadog-agent" + readOnly = false + } + ] + }, merge( { name = "datadog-agent" @@ -319,6 +399,8 @@ locals { dockerLabels = var.dd_docker_labels cpu = var.dd_cpu memory = var.dd_memory_limit_mib + + readonlyRootFilesystem = true secrets = var.dd_api_key_secret != null ? [ { name = "DD_API_KEY" @@ -337,7 +419,19 @@ locals { protocol = "tcp" } ], - mountPoints = local.apm_dsd_mount, + + dependsOn = [ + { + condition = "SUCCESS" + containerName = "init-config" + }, + { + condition = "SUCCESS" + containerName = "init-volume" + } + ] + + mountPoints = local.dd_agent_mount, logConfiguration = local.dd_firelens_log_configuration, dependsOn = try(var.dd_log_collection.fluentbit_config.is_log_router_dependency_enabled, false) && local.dd_firelens_log_configuration != null ? local.log_router_dependency : [], systemControls = [] From 69f0833c8e0cb8c7050b69f63c088d5f2353c7fa Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Thu, 30 Oct 2025 10:35:18 -0400 Subject: [PATCH 2/9] remove log volume to move logs to opt dir --- modules/ecs_fargate/datadog.tf | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/ecs_fargate/datadog.tf b/modules/ecs_fargate/datadog.tf index 4b02173..2f140ab 100644 --- a/modules/ecs_fargate/datadog.tf +++ b/modules/ecs_fargate/datadog.tf @@ -90,11 +90,6 @@ locals { sourceVolume = "agent-tmp" readOnly = false }, - { - containerPath = "/var/log/datadog" - sourceVolume = "agent-logs" - readOnly = false - }, { containerPath = "/opt/datadog-agent/run" sourceVolume = "agent-run" @@ -256,9 +251,6 @@ locals { { name = "agent-tmp" }, - { - name = "agent-logs" - }, { name = "agent-run" } @@ -306,6 +298,10 @@ locals { name = "DD_INSTALL_INFO_INSTALLER_VERSION" value = local.install_info_installer_version }, + { + name = "DD_LOG_FILE" + value = "/opt/datadog-agent/run/logs" + } ] dynamic_env = [ From d46c37e9b8ecb63e90845f521a86a2c621e66cf5 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Wed, 5 Nov 2025 18:19:40 -0500 Subject: [PATCH 3/9] feat: remove init-config --- modules/ecs_fargate/datadog.tf | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/modules/ecs_fargate/datadog.tf b/modules/ecs_fargate/datadog.tf index 2f140ab..0ab2367 100644 --- a/modules/ecs_fargate/datadog.tf +++ b/modules/ecs_fargate/datadog.tf @@ -299,7 +299,7 @@ locals { value = local.install_info_installer_version }, { - name = "DD_LOG_FILE" + name = "DD_LOG_FILE" value = "/opt/datadog-agent/run/logs" } ] @@ -364,28 +364,6 @@ locals { } ] }, - { - cpu = 0 - memory = 128 - name = "init-config" - image = "${var.dd_registry}:${var.dd_image_version}" - essential = false - readOnlyRootFilesystem = true - command = ["/bin/sh", "-c", "for script in $(find /etc/cont-init.d/ -type f -name '*.sh' | sort) ; do bash $script ; done"] - dependsOn = [ - { - condition = "SUCCESS" - containerName = "init-volume" - } - ] - mountPoints = [ - { - sourceVolume = "agent-config" - containerPath = "/etc/datadog-agent" - readOnly = false - } - ] - }, merge( { name = "datadog-agent" @@ -417,10 +395,6 @@ locals { ], dependsOn = [ - { - condition = "SUCCESS" - containerName = "init-config" - }, { condition = "SUCCESS" containerName = "init-volume" From 5d8e248277d026e80df82d55253a098c34d3b2b9 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Thu, 6 Nov 2025 10:54:27 -0500 Subject: [PATCH 4/9] test: fix expected container and volume mount count --- tests/all_dd_disabled_test.go | 9 ++++++--- tests/all_dd_inputs_test.go | 2 +- tests/apm_dsd_tcp_udp_test.go | 9 ++++++--- tests/logging_only_test.go | 5 ++--- tests/ust_docker_labels_test.go | 2 +- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/tests/all_dd_disabled_test.go b/tests/all_dd_disabled_test.go index d44efa3..a140296 100644 --- a/tests/all_dd_disabled_test.go +++ b/tests/all_dd_disabled_test.go @@ -26,7 +26,7 @@ func (s *ECSFargateSuite) TestAllDDDisabled() { err := json.Unmarshal([]byte(task["container_definitions"]), &containers) s.NoError(err, "Failed to parse container definitions") - s.Equal(2, len(containers), "Expected 2 containers in the task definition") + s.Equal(3, len(containers), "Expected 2 containers in the task definition") // Test Agent Container agentContainer, found := GetContainer(containers, "datadog-agent") @@ -59,8 +59,11 @@ func (s *ECSFargateSuite) TestAllDDDisabled() { s.Equal(int32(3), *agentContainer.HealthCheck.Retries, "Agent health check retries should be 3") s.Equal(int32(60), *agentContainer.HealthCheck.StartPeriod, "Agent health check start period should be 60") - // Verify no mount points (apm/dsd volumes should not be present) - s.Equal(0, len(agentContainer.MountPoints), "Expected no mount points for datadog-agent when features are disabled") + s.Equal(3, len(agentContainer.MountPoints), "Expected 3 mount points when features are disabled") + // Verify none are apm/dsd volume mount points + for _, mountPoint := range agentContainer.MountPoints { + s.NotEqual("dd-socket", *mountPoint.SourceVolume, "Mount point should not be dd-socket") + } // Test dummy container dummyContainer, found := GetContainer(containers, "dummy-container") diff --git a/tests/all_dd_inputs_test.go b/tests/all_dd_inputs_test.go index a03114b..2b5841c 100644 --- a/tests/all_dd_inputs_test.go +++ b/tests/all_dd_inputs_test.go @@ -25,7 +25,7 @@ func (s *ECSFargateSuite) TestAllDDInputs() { err := json.Unmarshal([]byte(task["container_definitions"]), &containers) s.NoError(err, "Failed to parse container definitions") - s.Equal(6, len(containers), "Expected 6 containers in the task definition") + s.Equal(7, len(containers), "Expected 6 containers in the task definition") // Test Agent Container agentContainer, found := GetContainer(containers, "datadog-agent") diff --git a/tests/apm_dsd_tcp_udp_test.go b/tests/apm_dsd_tcp_udp_test.go index 1a361bb..3f722e7 100644 --- a/tests/apm_dsd_tcp_udp_test.go +++ b/tests/apm_dsd_tcp_udp_test.go @@ -26,7 +26,7 @@ func (s *ECSFargateSuite) TestApmDsdTcpUdp() { err := json.Unmarshal([]byte(task["container_definitions"]), &containers) s.NoError(err, "Failed to parse container definitions") - s.Equal(3, len(containers), "Expected 3 containers in the task definition") + s.Equal(4, len(containers), "Expected 3 containers in the task definition") // Test Agent Container agentContainer, found := GetContainer(containers, "datadog-agent") @@ -60,8 +60,11 @@ func (s *ECSFargateSuite) TestApmDsdTcpUdp() { } AssertNotEnvVars(s.T(), agentContainer, disabledSocketEnvVars) - // Verify no mount points (as sockets are not used) - s.Equal(0, len(agentContainer.MountPoints), "Expected no mount points for datadog-agent when socket is disabled") + s.Equal(3, len(agentContainer.MountPoints), "Expected 3 mount points when socket is disabled") + // Verify none are apm/dsd volume mount points + for _, mountPoint := range agentContainer.MountPoints { + s.NotEqual("dd-socket", *mountPoint.SourceVolume, "Mount point should not be dd-socket") + } // Test DogStatsD App Container dogstatsdContainer, found := GetContainer(containers, "datadog-dogstatsd-app") diff --git a/tests/logging_only_test.go b/tests/logging_only_test.go index 92eba35..8147d61 100644 --- a/tests/logging_only_test.go +++ b/tests/logging_only_test.go @@ -26,7 +26,7 @@ func (s *ECSFargateSuite) TestLoggingOnly() { err := json.Unmarshal([]byte(task["container_definitions"]), &containers) s.NoError(err, "Failed to parse container definitions") - s.Equal(2, len(containers), "Expected 2 containers in the task definition") + s.Equal(3, len(containers), "Expected 2 containers in the task definition") // Test Agent Container agentContainer, found := GetContainer(containers, "datadog-agent") @@ -73,8 +73,7 @@ func (s *ECSFargateSuite) TestLoggingOnly() { s.Equal("datadog-log-router", *agentContainer.DependsOn[0].ContainerName, "Agent should depend on datadog-log-router") s.Equal(types.ContainerConditionHealthy, agentContainer.DependsOn[0].Condition, "Agent should depend on log router being healthy") - // Verify no mount points - s.Equal(0, len(agentContainer.MountPoints), "Expected no mount points for datadog-agent") + s.Equal(3, len(agentContainer.MountPoints), "Expected 3 mount points for datadog-agent") // Test Log Router Container logRouterContainer, found := GetContainer(containers, "datadog-log-router") diff --git a/tests/ust_docker_labels_test.go b/tests/ust_docker_labels_test.go index 6bde250..1cbd049 100644 --- a/tests/ust_docker_labels_test.go +++ b/tests/ust_docker_labels_test.go @@ -25,7 +25,7 @@ func (s *ECSFargateSuite) TestUSTDockerLabels() { err := json.Unmarshal([]byte(task["container_definitions"]), &containers) s.NoError(err, "Failed to parse container definitions") - s.Equal(4, len(containers), "Expected 4 containers in the task definition (1 app container + 3 agent sidecar)") + s.Equal(5, len(containers), "Expected 4 containers in the task definition (1 app container + 3 agent sidecar)") // Expected UST docker labels that should be present on all application containers expectedUSTLabels := map[string]string{ From 0e28eaffe3f3a24720bb474ff0b60f0285574ccd Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Thu, 6 Nov 2025 12:11:17 -0500 Subject: [PATCH 5/9] feat: add rofs configuration option --- modules/ecs_fargate/README.md | 1 + modules/ecs_fargate/datadog.tf | 142 ++++++++++++++++--------------- modules/ecs_fargate/variables.tf | 7 ++ 3 files changed, 82 insertions(+), 68 deletions(-) diff --git a/modules/ecs_fargate/README.md b/modules/ecs_fargate/README.md index f361015..04a61ba 100644 --- a/modules/ecs_fargate/README.md +++ b/modules/ecs_fargate/README.md @@ -255,6 +255,7 @@ No modules. | [dd\_is\_datadog\_dependency\_enabled](#input\_dd\_is\_datadog\_dependency\_enabled) | Whether the Datadog Agent container is a dependency for other containers | `bool` | `false` | no | | [dd\_log\_collection](#input\_dd\_log\_collection) | Configuration for Datadog Log Collection |
object({
enabled = optional(bool, false)
fluentbit_config = optional(object({
registry = optional(string, "public.ecr.aws/aws-observability/aws-for-fluent-bit")
image_version = optional(string, "stable")
cpu = optional(number)
memory_limit_mib = optional(number)
is_log_router_essential = optional(bool, false)
is_log_router_dependency_enabled = optional(bool, false)
environment = optional(list(object({
name = string
value = string
})), [])
log_router_health_check = optional(object({
command = optional(list(string))
interval = optional(number)
retries = optional(number)
start_period = optional(number)
timeout = optional(number)
}),
{
command = ["CMD-SHELL", "exit 0"]
interval = 5
retries = 3
start_period = 15
timeout = 5
}
)
firelens_options = optional(object({
config_file_type = optional(string)
config_file_value = optional(string)
}))
log_driver_configuration = optional(object({
host_endpoint = optional(string, "http-intake.logs.datadoghq.com")
tls = optional(bool)
compress = optional(string)
service_name = optional(string)
source_name = optional(string)
message_key = optional(string)
}),
{
host_endpoint = "http-intake.logs.datadoghq.com"
}
)
mountPoints = optional(list(object({
sourceVolume : string,
containerPath : string,
readOnly : bool
})), [])
dependsOn = optional(list(object({
containerName : string,
condition : string
})), [])
}),
{
fluentbit_config = {
registry = "public.ecr.aws/aws-observability/aws-for-fluent-bit"
image_version = "stable"
log_driver_configuration = {
host_endpoint = "http-intake.logs.datadoghq.com"
}
}
}
)
})
|
{
"enabled": false,
"fluentbit_config": {
"is_log_router_essential": false,
"log_driver_configuration": {
"host_endpoint": "http-intake.logs.datadoghq.com"
}
}
}
| no | | [dd\_memory\_limit\_mib](#input\_dd\_memory\_limit\_mib) | Datadog Agent container memory limit in MiB | `number` | `null` | no | +| [dd\_readonly\_root\_filesystem](#input\_dd\_readonly\_root\_filesystem) | Datadog Agent container runs with read-only root filesystem enabled | `bool` | `true` | no | | [dd\_registry](#input\_dd\_registry) | Datadog Agent image registry | `string` | `"public.ecr.aws/datadog/agent"` | no | | [dd\_service](#input\_dd\_service) | The task service name. Used for tagging (UST) | `string` | `null` | no | | [dd\_site](#input\_dd\_site) | Datadog Site | `string` | `"datadoghq.com"` | no | diff --git a/modules/ecs_fargate/datadog.tf b/modules/ecs_fargate/datadog.tf index 0ab2367..9ce1f27 100644 --- a/modules/ecs_fargate/datadog.tf +++ b/modules/ecs_fargate/datadog.tf @@ -244,7 +244,7 @@ locals { ) ] - rofs_volumes = [ + rofs_volumes = var.dd_readonly_root_filesystem ? [ { name = "agent-config" }, @@ -254,7 +254,14 @@ locals { { name = "agent-run" } - ] + ] : [] + + rofs_agent_depends_on = var.dd_readonly_root_filesystem ? [ + { + condition = "SUCCESS" + containerName = "init-volume" + } + ] : [] # Volume configuration for task apm_dsd_volume = local.is_apm_dsd_volume ? [ @@ -347,77 +354,76 @@ locals { ) # Datadog Agent container definition - dd_agent_container = [ - { - cpu = 0 - memory = 128 - name = "init-volume" - image = "${var.dd_registry}:${var.dd_image_version}" - essential = false - readOnlyRootFilesystem = true - command = ["/bin/sh", "-c", "cp -vnR /etc/datadog-agent/* /agent-config/ && exit 0"] - mountPoints = [ - { - sourceVolume = "agent-config" - containerPath = "/agent-config" - readOnly = false - } - ] - }, - merge( + dd_agent_container = concat( + var.dd_readonly_root_filesystem ? [ { - name = "datadog-agent" - image = "${var.dd_registry}:${var.dd_image_version}" - essential = var.dd_essential - environment = local.dd_agent_env - dockerLabels = var.dd_docker_labels - cpu = var.dd_cpu - memory = var.dd_memory_limit_mib - - readonlyRootFilesystem = true - secrets = var.dd_api_key_secret != null ? [ - { - name = "DD_API_KEY" - valueFrom = var.dd_api_key_secret.arn - } - ] : [] - portMappings = [ + cpu = 0 + memory = 128 + name = "init-volume" + image = "${var.dd_registry}:${var.dd_image_version}" + essential = false + readOnlyRootFilesystem = true + command = ["/bin/sh", "-c", "cp -vnR /etc/datadog-agent/* /agent-config/ && exit 0"] + mountPoints = [ { - containerPort = 8125 - hostPort = 8125 - protocol = "udp" - }, - { - containerPort = 8126 - hostPort = 8126 - protocol = "tcp" - } - ], - - dependsOn = [ - { - condition = "SUCCESS" - containerName = "init-volume" + sourceVolume = "agent-config" + containerPath = "/agent-config" + readOnly = false } ] - - mountPoints = local.dd_agent_mount, - logConfiguration = local.dd_firelens_log_configuration, - dependsOn = try(var.dd_log_collection.fluentbit_config.is_log_router_dependency_enabled, false) && local.dd_firelens_log_configuration != null ? local.log_router_dependency : [], - systemControls = [] - volumesFrom = [] - }, - try(var.dd_health_check.command == null, true) ? {} : { - healthCheck = { - command = var.dd_health_check.command - interval = var.dd_health_check.interval - timeout = var.dd_health_check.timeout - retries = var.dd_health_check.retries - startPeriod = var.dd_health_check.start_period - } } - ) - ] + ] : [], + [ + merge( + { + name = "datadog-agent" + image = "${var.dd_registry}:${var.dd_image_version}" + essential = var.dd_essential + environment = local.dd_agent_env + dockerLabels = var.dd_docker_labels + cpu = var.dd_cpu + memory = var.dd_memory_limit_mib + + readonlyRootFilesystem = var.dd_readonly_root_filesystem + secrets = var.dd_api_key_secret != null ? [ + { + name = "DD_API_KEY" + valueFrom = var.dd_api_key_secret.arn + } + ] : [] + portMappings = [ + { + containerPort = 8125 + hostPort = 8125 + protocol = "udp" + }, + { + containerPort = 8126 + hostPort = 8126 + protocol = "tcp" + } + ], + + dependsOn = local.rofs_agent_depends_on, + + mountPoints = local.dd_agent_mount, + logConfiguration = local.dd_firelens_log_configuration, + dependsOn = try(var.dd_log_collection.fluentbit_config.is_log_router_dependency_enabled, false) && local.dd_firelens_log_configuration != null ? local.log_router_dependency : [], + systemControls = [] + volumesFrom = [] + }, + try(var.dd_health_check.command == null, true) ? {} : { + healthCheck = { + command = var.dd_health_check.command + interval = var.dd_health_check.interval + timeout = var.dd_health_check.timeout + retries = var.dd_health_check.retries + startPeriod = var.dd_health_check.start_period + } + } + ) + ] + ) dd_log_environment = var.dd_log_collection.fluentbit_config.environment != null ? var.dd_log_collection.fluentbit_config.environment : [] diff --git a/modules/ecs_fargate/variables.tf b/modules/ecs_fargate/variables.tf index d5cc82e..00245e2 100644 --- a/modules/ecs_fargate/variables.tf +++ b/modules/ecs_fargate/variables.tf @@ -65,6 +65,13 @@ variable "dd_is_datadog_dependency_enabled" { nullable = false } +variable "dd_readonly_root_filesystem" { + description = "Datadog Agent container runs with read-only root filesystem enabled" + type = bool + default = true + nullable = false +} + variable "dd_health_check" { description = "Datadog Agent health check configuration" type = object({ From 2545a826cce2b823cc0ed5e55796208722e3ff60 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Thu, 6 Nov 2025 12:21:54 -0500 Subject: [PATCH 6/9] test: add rofs disabled to dd disabled test --- modules/ecs_fargate/datadog.tf | 4 ++-- smoke_tests/ecs_fargate/all-dd-disabled.tf | 1 + tests/all_dd_disabled_test.go | 8 ++------ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/modules/ecs_fargate/datadog.tf b/modules/ecs_fargate/datadog.tf index 9ce1f27..6a0accf 100644 --- a/modules/ecs_fargate/datadog.tf +++ b/modules/ecs_fargate/datadog.tf @@ -79,7 +79,7 @@ locals { dd_agent_mount = concat( local.apm_dsd_mount, - [ + var.dd_readonly_root_filesystem ? [ { containerPath = "/etc/datadog-agent" sourceVolume = "agent-config" @@ -95,7 +95,7 @@ locals { sourceVolume = "agent-run" readOnly = false } - ] + ] : [] ) apm_socket_var = local.is_apm_socket_mount ? [ diff --git a/smoke_tests/ecs_fargate/all-dd-disabled.tf b/smoke_tests/ecs_fargate/all-dd-disabled.tf index 46aab76..ef913ea 100644 --- a/smoke_tests/ecs_fargate/all-dd-disabled.tf +++ b/smoke_tests/ecs_fargate/all-dd-disabled.tf @@ -17,6 +17,7 @@ module "dd_task_all_dd_disabled" { dd_tags = "team:cont-p, owner:container-monitoring" dd_essential = true dd_is_datadog_dependency_enabled = false + dd_readonly_root_filesystem = false dd_environment = [] diff --git a/tests/all_dd_disabled_test.go b/tests/all_dd_disabled_test.go index a140296..2b8963e 100644 --- a/tests/all_dd_disabled_test.go +++ b/tests/all_dd_disabled_test.go @@ -26,7 +26,7 @@ func (s *ECSFargateSuite) TestAllDDDisabled() { err := json.Unmarshal([]byte(task["container_definitions"]), &containers) s.NoError(err, "Failed to parse container definitions") - s.Equal(3, len(containers), "Expected 2 containers in the task definition") + s.Equal(2, len(containers), "Expected 2 containers in the task definition") // Test Agent Container agentContainer, found := GetContainer(containers, "datadog-agent") @@ -59,11 +59,7 @@ func (s *ECSFargateSuite) TestAllDDDisabled() { s.Equal(int32(3), *agentContainer.HealthCheck.Retries, "Agent health check retries should be 3") s.Equal(int32(60), *agentContainer.HealthCheck.StartPeriod, "Agent health check start period should be 60") - s.Equal(3, len(agentContainer.MountPoints), "Expected 3 mount points when features are disabled") - // Verify none are apm/dsd volume mount points - for _, mountPoint := range agentContainer.MountPoints { - s.NotEqual("dd-socket", *mountPoint.SourceVolume, "Mount point should not be dd-socket") - } + s.Equal(0, len(agentContainer.MountPoints), "Expected no mount points when features are disabled") // Test dummy container dummyContainer, found := GetContainer(containers, "dummy-container") From bbf05de2fcbcf08795e6092902bf228fe6d6187f Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Thu, 6 Nov 2025 13:39:50 -0500 Subject: [PATCH 7/9] chore: merge dependson and test for rofs volume mounts --- modules/ecs_fargate/datadog.tf | 21 +++++++++++---------- smoke_tests/ecs_fargate/logging-only.tf | 2 ++ tests/all_dd_inputs_test.go | 7 +++++++ tests/logging_only_test.go | 4 ++-- tests/utils.go | 4 ++++ 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/modules/ecs_fargate/datadog.tf b/modules/ecs_fargate/datadog.tf index 6a0accf..e2ce992 100644 --- a/modules/ecs_fargate/datadog.tf +++ b/modules/ecs_fargate/datadog.tf @@ -256,13 +256,6 @@ locals { } ] : [] - rofs_agent_depends_on = var.dd_readonly_root_filesystem ? [ - { - condition = "SUCCESS" - containerName = "init-volume" - } - ] : [] - # Volume configuration for task apm_dsd_volume = local.is_apm_dsd_volume ? [ { @@ -353,6 +346,16 @@ locals { local.dd_environment, ) + dd_agent_dependency = concat( + var.dd_readonly_root_filesystem ? [ + { + condition = "SUCCESS" + containerName = "init-volume" + } + ] : [], + try(var.dd_log_collection.fluentbit_config.is_log_router_dependency_enabled, false) && local.dd_firelens_log_configuration != null ? local.log_router_dependency : [], + ) + # Datadog Agent container definition dd_agent_container = concat( var.dd_readonly_root_filesystem ? [ @@ -404,11 +407,9 @@ locals { } ], - dependsOn = local.rofs_agent_depends_on, - mountPoints = local.dd_agent_mount, logConfiguration = local.dd_firelens_log_configuration, - dependsOn = try(var.dd_log_collection.fluentbit_config.is_log_router_dependency_enabled, false) && local.dd_firelens_log_configuration != null ? local.log_router_dependency : [], + dependsOn = local.dd_agent_dependency systemControls = [] volumesFrom = [] }, diff --git a/smoke_tests/ecs_fargate/logging-only.tf b/smoke_tests/ecs_fargate/logging-only.tf index 1caa355..12015e5 100644 --- a/smoke_tests/ecs_fargate/logging-only.tf +++ b/smoke_tests/ecs_fargate/logging-only.tf @@ -15,6 +15,8 @@ module "dd_task_logging_only" { dd_service = var.dd_service dd_essential = true + dd_readonly_root_filesystem = false + dd_dogstatsd = { enabled = false, } diff --git a/tests/all_dd_inputs_test.go b/tests/all_dd_inputs_test.go index 2b5841c..b198ad3 100644 --- a/tests/all_dd_inputs_test.go +++ b/tests/all_dd_inputs_test.go @@ -27,6 +27,10 @@ func (s *ECSFargateSuite) TestAllDDInputs() { s.NoError(err, "Failed to parse container definitions") s.Equal(7, len(containers), "Expected 6 containers in the task definition") + initContainer, found := GetContainer(containers, "init-volume") + s.True(found, "Container init-volume not found in definitions") + AssertMountPoint(s.T(), initContainer, MountInitVolume) + // Test Agent Container agentContainer, found := GetContainer(containers, "datadog-agent") s.True(found, "Container datadog-agent not found in definitions") @@ -37,6 +41,9 @@ func (s *ECSFargateSuite) TestAllDDInputs() { AssertPortMapping(s.T(), agentContainer, PortUDP) AssertPortMapping(s.T(), agentContainer, PortTCP) AssertMountPoint(s.T(), agentContainer, MountDdSocket) + AssertMountPoint(s.T(), agentContainer, MountAgentConfig) + AssertMountPoint(s.T(), agentContainer, MountAgentTmp) + AssertMountPoint(s.T(), agentContainer, MountAgentRun) AssertContainerDependency(s.T(), agentContainer, DependencyLogRouter) expectedAgentEnvvars := map[string]string{ diff --git a/tests/logging_only_test.go b/tests/logging_only_test.go index 8147d61..f9218e4 100644 --- a/tests/logging_only_test.go +++ b/tests/logging_only_test.go @@ -26,7 +26,7 @@ func (s *ECSFargateSuite) TestLoggingOnly() { err := json.Unmarshal([]byte(task["container_definitions"]), &containers) s.NoError(err, "Failed to parse container definitions") - s.Equal(3, len(containers), "Expected 2 containers in the task definition") + s.Equal(2, len(containers), "Expected 2 containers in the task definition") // Test Agent Container agentContainer, found := GetContainer(containers, "datadog-agent") @@ -73,7 +73,7 @@ func (s *ECSFargateSuite) TestLoggingOnly() { s.Equal("datadog-log-router", *agentContainer.DependsOn[0].ContainerName, "Agent should depend on datadog-log-router") s.Equal(types.ContainerConditionHealthy, agentContainer.DependsOn[0].Condition, "Agent should depend on log router being healthy") - s.Equal(3, len(agentContainer.MountPoints), "Expected 3 mount points for datadog-agent") + s.Equal(0, len(agentContainer.MountPoints), "Expected 2 mount points for datadog-agent") // Test Log Router Container logRouterContainer, found := GetContainer(containers, "datadog-log-router") diff --git a/tests/utils.go b/tests/utils.go index d372f3b..2b679d7 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -16,6 +16,10 @@ import ( var ( MountDdSocket = types.MountPoint{SourceVolume: aws.String("dd-sockets"), ContainerPath: aws.String("/var/run/datadog"), ReadOnly: aws.Bool(false)} MountCWS = types.MountPoint{SourceVolume: aws.String("cws-instrumentation-volume"), ContainerPath: aws.String("/cws-instrumentation-volume"), ReadOnly: aws.Bool(false)} + MountInitVolume = types.MountPoint{SourceVolume: aws.String("agent-config"), ContainerPath: aws.String("/agent-config"), ReadOnly: aws.Bool(false)} + MountAgentConfig = types.MountPoint{SourceVolume: aws.String("agent-config"), ContainerPath: aws.String("/etc/datadog-agent"), ReadOnly: aws.Bool(false)} + MountAgentTmp = types.MountPoint{SourceVolume: aws.String("agent-tmp"), ContainerPath: aws.String("/tmp"), ReadOnly: aws.Bool(false)} + MountAgentRun = types.MountPoint{SourceVolume: aws.String("agent-run"), ContainerPath: aws.String("/opt/datadog-agent/run"), ReadOnly: aws.Bool(false)} PortTCP = types.PortMapping{ContainerPort: aws.Int32(8126), HostPort: aws.Int32(8126), Protocol: types.TransportProtocolTcp} PortUDP = types.PortMapping{ContainerPort: aws.Int32(8125), HostPort: aws.Int32(8125), Protocol: types.TransportProtocolUdp} DependencyAgent = types.ContainerDependency{ContainerName: aws.String("datadog-agent"), Condition: types.ContainerConditionHealthy} From 06b41ef9ab3cd4873e6c8e333f4a9de67642c816 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Thu, 6 Nov 2025 14:31:54 -0500 Subject: [PATCH 8/9] feat: add precondition linux only for rofs --- modules/ecs_fargate/main.tf | 4 ++++ smoke_tests/ecs_fargate/all-windows.tf | 2 ++ 2 files changed, 6 insertions(+) diff --git a/modules/ecs_fargate/main.tf b/modules/ecs_fargate/main.tf index 28213a6..16d189a 100644 --- a/modules/ecs_fargate/main.tf +++ b/modules/ecs_fargate/main.tf @@ -177,6 +177,10 @@ resource "aws_ecs_task_definition" "this" { condition = var.dd_log_collection.enabled == false || (var.dd_log_collection.enabled == true && local.is_linux == true) error_message = "Log collection is not supported on Windows. Please set `dd_log_collection.enabled` to `false`." } + precondition { + condition = var.dd_readonly_root_filesystem == false || (var.dd_readonly_root_filesystem == true && local.is_linux == true) + error_message = "Readonly root filesystem is only supported on Linux. Please set `dd_readonly_root_filesystem` to `false`." + } # Must provide only one of the two Datadog API key options precondition { condition = (var.dd_api_key == null && var.dd_api_key_secret != null) || (var.dd_api_key != null && var.dd_api_key_secret == null) diff --git a/smoke_tests/ecs_fargate/all-windows.tf b/smoke_tests/ecs_fargate/all-windows.tf index a0946bb..0ac9526 100644 --- a/smoke_tests/ecs_fargate/all-windows.tf +++ b/smoke_tests/ecs_fargate/all-windows.tf @@ -16,6 +16,8 @@ module "dd_task_all_windows" { dd_site = var.dd_site dd_service = var.dd_service + dd_readonly_root_filesystem = false + dd_apm = { enabled = true } From b3605a6b060465cc7a639212eb9d5c6bc856c4c1 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Fri, 7 Nov 2025 11:30:15 -0500 Subject: [PATCH 9/9] feat: dd_readonly_root_filesystem false by default --- modules/ecs_fargate/README.md | 2 +- modules/ecs_fargate/variables.tf | 2 +- smoke_tests/ecs_fargate/all-dd-inputs.tf | 1 + smoke_tests/ecs_fargate/apm-dsd-tcp-udp.tf | 2 ++ smoke_tests/ecs_fargate/ust-docker-labels.tf | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/ecs_fargate/README.md b/modules/ecs_fargate/README.md index 04a61ba..4b9f0b6 100644 --- a/modules/ecs_fargate/README.md +++ b/modules/ecs_fargate/README.md @@ -255,7 +255,7 @@ No modules. | [dd\_is\_datadog\_dependency\_enabled](#input\_dd\_is\_datadog\_dependency\_enabled) | Whether the Datadog Agent container is a dependency for other containers | `bool` | `false` | no | | [dd\_log\_collection](#input\_dd\_log\_collection) | Configuration for Datadog Log Collection |
object({
enabled = optional(bool, false)
fluentbit_config = optional(object({
registry = optional(string, "public.ecr.aws/aws-observability/aws-for-fluent-bit")
image_version = optional(string, "stable")
cpu = optional(number)
memory_limit_mib = optional(number)
is_log_router_essential = optional(bool, false)
is_log_router_dependency_enabled = optional(bool, false)
environment = optional(list(object({
name = string
value = string
})), [])
log_router_health_check = optional(object({
command = optional(list(string))
interval = optional(number)
retries = optional(number)
start_period = optional(number)
timeout = optional(number)
}),
{
command = ["CMD-SHELL", "exit 0"]
interval = 5
retries = 3
start_period = 15
timeout = 5
}
)
firelens_options = optional(object({
config_file_type = optional(string)
config_file_value = optional(string)
}))
log_driver_configuration = optional(object({
host_endpoint = optional(string, "http-intake.logs.datadoghq.com")
tls = optional(bool)
compress = optional(string)
service_name = optional(string)
source_name = optional(string)
message_key = optional(string)
}),
{
host_endpoint = "http-intake.logs.datadoghq.com"
}
)
mountPoints = optional(list(object({
sourceVolume : string,
containerPath : string,
readOnly : bool
})), [])
dependsOn = optional(list(object({
containerName : string,
condition : string
})), [])
}),
{
fluentbit_config = {
registry = "public.ecr.aws/aws-observability/aws-for-fluent-bit"
image_version = "stable"
log_driver_configuration = {
host_endpoint = "http-intake.logs.datadoghq.com"
}
}
}
)
})
|
{
"enabled": false,
"fluentbit_config": {
"is_log_router_essential": false,
"log_driver_configuration": {
"host_endpoint": "http-intake.logs.datadoghq.com"
}
}
}
| no | | [dd\_memory\_limit\_mib](#input\_dd\_memory\_limit\_mib) | Datadog Agent container memory limit in MiB | `number` | `null` | no | -| [dd\_readonly\_root\_filesystem](#input\_dd\_readonly\_root\_filesystem) | Datadog Agent container runs with read-only root filesystem enabled | `bool` | `true` | no | +| [dd\_readonly\_root\_filesystem](#input\_dd\_readonly\_root\_filesystem) | Datadog Agent container runs with read-only root filesystem enabled | `bool` | `false` | no | | [dd\_registry](#input\_dd\_registry) | Datadog Agent image registry | `string` | `"public.ecr.aws/datadog/agent"` | no | | [dd\_service](#input\_dd\_service) | The task service name. Used for tagging (UST) | `string` | `null` | no | | [dd\_site](#input\_dd\_site) | Datadog Site | `string` | `"datadoghq.com"` | no | diff --git a/modules/ecs_fargate/variables.tf b/modules/ecs_fargate/variables.tf index 00245e2..9f91715 100644 --- a/modules/ecs_fargate/variables.tf +++ b/modules/ecs_fargate/variables.tf @@ -68,7 +68,7 @@ variable "dd_is_datadog_dependency_enabled" { variable "dd_readonly_root_filesystem" { description = "Datadog Agent container runs with read-only root filesystem enabled" type = bool - default = true + default = false nullable = false } diff --git a/smoke_tests/ecs_fargate/all-dd-inputs.tf b/smoke_tests/ecs_fargate/all-dd-inputs.tf index 54f1951..2da83cd 100644 --- a/smoke_tests/ecs_fargate/all-dd-inputs.tf +++ b/smoke_tests/ecs_fargate/all-dd-inputs.tf @@ -17,6 +17,7 @@ module "dd_task_all_dd_inputs" { dd_tags = "team:cont-p, owner:container-monitoring" dd_essential = true dd_is_datadog_dependency_enabled = true + dd_readonly_root_filesystem = true dd_environment = [ { diff --git a/smoke_tests/ecs_fargate/apm-dsd-tcp-udp.tf b/smoke_tests/ecs_fargate/apm-dsd-tcp-udp.tf index e5f66d6..1bda78d 100644 --- a/smoke_tests/ecs_fargate/apm-dsd-tcp-udp.tf +++ b/smoke_tests/ecs_fargate/apm-dsd-tcp-udp.tf @@ -18,6 +18,8 @@ module "dd_task_apm_dsd_tcp_udp" { dd_tags = "team:cont-p, owner:container-monitoring" dd_essential = true + dd_readonly_root_filesystem = true + dd_dogstatsd = { enabled = true, socket_enabled = false, diff --git a/smoke_tests/ecs_fargate/ust-docker-labels.tf b/smoke_tests/ecs_fargate/ust-docker-labels.tf index d614c58..592db4b 100644 --- a/smoke_tests/ecs_fargate/ust-docker-labels.tf +++ b/smoke_tests/ecs_fargate/ust-docker-labels.tf @@ -20,6 +20,7 @@ module "dd_task_ust_docker_labels" { dd_essential = true dd_is_datadog_dependency_enabled = true + dd_readonly_root_filesystem = true dd_log_collection = { enabled = true,