Skip to content

Commit c255688

Browse files
[CONTP-921] Configure read-only root filesystem for Datadog Agent (#49)
* use init config and volume containers for rofs * remove log volume to move logs to opt dir * feat: remove init-config * test: fix expected container and volume mount count * feat: add rofs configuration option * test: add rofs disabled to dd disabled test * chore: merge dependson and test for rofs volume mounts * feat: add precondition linux only for rofs * feat: dd_readonly_root_filesystem false by default
1 parent ebc1db9 commit c255688

16 files changed

+153
-49
lines changed

modules/ecs_fargate/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ No modules.
255255
| <a name="input_dd_is_datadog_dependency_enabled"></a> [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 |
256256
| <a name="input_dd_log_collection"></a> [dd\_log\_collection](#input\_dd\_log\_collection) | Configuration for Datadog Log Collection | <pre>object({<br/> enabled = optional(bool, false)<br/> fluentbit_config = optional(object({<br/> registry = optional(string, "public.ecr.aws/aws-observability/aws-for-fluent-bit")<br/> image_version = optional(string, "stable")<br/> cpu = optional(number)<br/> memory_limit_mib = optional(number)<br/> is_log_router_essential = optional(bool, false)<br/> is_log_router_dependency_enabled = optional(bool, false)<br/> environment = optional(list(object({<br/> name = string<br/> value = string<br/> })), [])<br/> log_router_health_check = optional(object({<br/> command = optional(list(string))<br/> interval = optional(number)<br/> retries = optional(number)<br/> start_period = optional(number)<br/> timeout = optional(number)<br/> }),<br/> {<br/> command = ["CMD-SHELL", "exit 0"]<br/> interval = 5<br/> retries = 3<br/> start_period = 15<br/> timeout = 5<br/> }<br/> )<br/> firelens_options = optional(object({<br/> config_file_type = optional(string)<br/> config_file_value = optional(string)<br/> }))<br/> log_driver_configuration = optional(object({<br/> host_endpoint = optional(string, "http-intake.logs.datadoghq.com")<br/> tls = optional(bool)<br/> compress = optional(string)<br/> service_name = optional(string)<br/> source_name = optional(string)<br/> message_key = optional(string)<br/> }),<br/> {<br/> host_endpoint = "http-intake.logs.datadoghq.com"<br/> }<br/> )<br/> mountPoints = optional(list(object({<br/> sourceVolume : string,<br/> containerPath : string,<br/> readOnly : bool<br/> })), [])<br/> dependsOn = optional(list(object({<br/> containerName : string,<br/> condition : string<br/> })), [])<br/> }),<br/> {<br/> fluentbit_config = {<br/> registry = "public.ecr.aws/aws-observability/aws-for-fluent-bit"<br/> image_version = "stable"<br/> log_driver_configuration = {<br/> host_endpoint = "http-intake.logs.datadoghq.com"<br/> }<br/> }<br/> }<br/> )<br/> })</pre> | <pre>{<br/> "enabled": false,<br/> "fluentbit_config": {<br/> "is_log_router_essential": false,<br/> "log_driver_configuration": {<br/> "host_endpoint": "http-intake.logs.datadoghq.com"<br/> }<br/> }<br/>}</pre> | no |
257257
| <a name="input_dd_memory_limit_mib"></a> [dd\_memory\_limit\_mib](#input\_dd\_memory\_limit\_mib) | Datadog Agent container memory limit in MiB | `number` | `null` | no |
258+
| <a name="input_dd_readonly_root_filesystem"></a> [dd\_readonly\_root\_filesystem](#input\_dd\_readonly\_root\_filesystem) | Datadog Agent container runs with read-only root filesystem enabled | `bool` | `false` | no |
258259
| <a name="input_dd_registry"></a> [dd\_registry](#input\_dd\_registry) | Datadog Agent image registry | `string` | `"public.ecr.aws/datadog/agent"` | no |
259260
| <a name="input_dd_service"></a> [dd\_service](#input\_dd\_service) | The task service name. Used for tagging (UST) | `string` | `null` | no |
260261
| <a name="input_dd_site"></a> [dd\_site](#input\_dd\_site) | Datadog Site | `string` | `"datadoghq.com"` | no |

modules/ecs_fargate/datadog.tf

Lines changed: 111 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,27 @@ locals {
7777
}
7878
] : []
7979

80+
dd_agent_mount = concat(
81+
local.apm_dsd_mount,
82+
var.dd_readonly_root_filesystem ? [
83+
{
84+
containerPath = "/etc/datadog-agent"
85+
sourceVolume = "agent-config"
86+
readOnly = false
87+
},
88+
{
89+
containerPath = "/tmp"
90+
sourceVolume = "agent-tmp"
91+
readOnly = false
92+
},
93+
{
94+
containerPath = "/opt/datadog-agent/run"
95+
sourceVolume = "agent-run"
96+
readOnly = false
97+
}
98+
] : []
99+
)
100+
80101
apm_socket_var = local.is_apm_socket_mount ? [
81102
{
82103
name = "DD_TRACE_AGENT_URL"
@@ -223,6 +244,18 @@ locals {
223244
)
224245
]
225246

247+
rofs_volumes = var.dd_readonly_root_filesystem ? [
248+
{
249+
name = "agent-config"
250+
},
251+
{
252+
name = "agent-tmp"
253+
},
254+
{
255+
name = "agent-run"
256+
}
257+
] : []
258+
226259
# Volume configuration for task
227260
apm_dsd_volume = local.is_apm_dsd_volume ? [
228261
{
@@ -238,6 +271,7 @@ locals {
238271

239272
modified_volumes = concat(
240273
[for k, v in coalesce(var.volumes, []) : v],
274+
local.rofs_volumes,
241275
local.apm_dsd_volume,
242276
local.cws_volume,
243277
)
@@ -264,6 +298,10 @@ locals {
264298
name = "DD_INSTALL_INFO_INSTALLER_VERSION"
265299
value = local.install_info_installer_version
266300
},
301+
{
302+
name = "DD_LOG_FILE"
303+
value = "/opt/datadog-agent/run/logs"
304+
}
267305
]
268306

269307
dynamic_env = [
@@ -308,52 +346,85 @@ locals {
308346
local.dd_environment,
309347
)
310348

349+
dd_agent_dependency = concat(
350+
var.dd_readonly_root_filesystem ? [
351+
{
352+
condition = "SUCCESS"
353+
containerName = "init-volume"
354+
}
355+
] : [],
356+
try(var.dd_log_collection.fluentbit_config.is_log_router_dependency_enabled, false) && local.dd_firelens_log_configuration != null ? local.log_router_dependency : [],
357+
)
358+
311359
# Datadog Agent container definition
312-
dd_agent_container = [
313-
merge(
360+
dd_agent_container = concat(
361+
var.dd_readonly_root_filesystem ? [
314362
{
315-
name = "datadog-agent"
316-
image = "${var.dd_registry}:${var.dd_image_version}"
317-
essential = var.dd_essential
318-
environment = local.dd_agent_env
319-
dockerLabels = var.dd_docker_labels
320-
cpu = var.dd_cpu
321-
memory = var.dd_memory_limit_mib
322-
secrets = var.dd_api_key_secret != null ? [
363+
cpu = 0
364+
memory = 128
365+
name = "init-volume"
366+
image = "${var.dd_registry}:${var.dd_image_version}"
367+
essential = false
368+
readOnlyRootFilesystem = true
369+
command = ["/bin/sh", "-c", "cp -vnR /etc/datadog-agent/* /agent-config/ && exit 0"]
370+
mountPoints = [
323371
{
324-
name = "DD_API_KEY"
325-
valueFrom = var.dd_api_key_secret.arn
372+
sourceVolume = "agent-config"
373+
containerPath = "/agent-config"
374+
readOnly = false
326375
}
327-
] : []
328-
portMappings = [
329-
{
330-
containerPort = 8125
331-
hostPort = 8125
332-
protocol = "udp"
333-
},
334-
{
335-
containerPort = 8126
336-
hostPort = 8126
337-
protocol = "tcp"
376+
]
377+
}
378+
] : [],
379+
[
380+
merge(
381+
{
382+
name = "datadog-agent"
383+
image = "${var.dd_registry}:${var.dd_image_version}"
384+
essential = var.dd_essential
385+
environment = local.dd_agent_env
386+
dockerLabels = var.dd_docker_labels
387+
cpu = var.dd_cpu
388+
memory = var.dd_memory_limit_mib
389+
390+
readonlyRootFilesystem = var.dd_readonly_root_filesystem
391+
secrets = var.dd_api_key_secret != null ? [
392+
{
393+
name = "DD_API_KEY"
394+
valueFrom = var.dd_api_key_secret.arn
395+
}
396+
] : []
397+
portMappings = [
398+
{
399+
containerPort = 8125
400+
hostPort = 8125
401+
protocol = "udp"
402+
},
403+
{
404+
containerPort = 8126
405+
hostPort = 8126
406+
protocol = "tcp"
407+
}
408+
],
409+
410+
mountPoints = local.dd_agent_mount,
411+
logConfiguration = local.dd_firelens_log_configuration,
412+
dependsOn = local.dd_agent_dependency
413+
systemControls = []
414+
volumesFrom = []
415+
},
416+
try(var.dd_health_check.command == null, true) ? {} : {
417+
healthCheck = {
418+
command = var.dd_health_check.command
419+
interval = var.dd_health_check.interval
420+
timeout = var.dd_health_check.timeout
421+
retries = var.dd_health_check.retries
422+
startPeriod = var.dd_health_check.start_period
338423
}
339-
],
340-
mountPoints = local.apm_dsd_mount,
341-
logConfiguration = local.dd_firelens_log_configuration,
342-
dependsOn = try(var.dd_log_collection.fluentbit_config.is_log_router_dependency_enabled, false) && local.dd_firelens_log_configuration != null ? local.log_router_dependency : [],
343-
systemControls = []
344-
volumesFrom = []
345-
},
346-
try(var.dd_health_check.command == null, true) ? {} : {
347-
healthCheck = {
348-
command = var.dd_health_check.command
349-
interval = var.dd_health_check.interval
350-
timeout = var.dd_health_check.timeout
351-
retries = var.dd_health_check.retries
352-
startPeriod = var.dd_health_check.start_period
353424
}
354-
}
355-
)
356-
]
425+
)
426+
]
427+
)
357428

358429
dd_log_environment = var.dd_log_collection.fluentbit_config.environment != null ? var.dd_log_collection.fluentbit_config.environment : []
359430

modules/ecs_fargate/main.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ resource "aws_ecs_task_definition" "this" {
177177
condition = var.dd_log_collection.enabled == false || (var.dd_log_collection.enabled == true && local.is_linux == true)
178178
error_message = "Log collection is not supported on Windows. Please set `dd_log_collection.enabled` to `false`."
179179
}
180+
precondition {
181+
condition = var.dd_readonly_root_filesystem == false || (var.dd_readonly_root_filesystem == true && local.is_linux == true)
182+
error_message = "Readonly root filesystem is only supported on Linux. Please set `dd_readonly_root_filesystem` to `false`."
183+
}
180184
# Must provide only one of the two Datadog API key options
181185
precondition {
182186
condition = (var.dd_api_key == null && var.dd_api_key_secret != null) || (var.dd_api_key != null && var.dd_api_key_secret == null)

modules/ecs_fargate/variables.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ variable "dd_is_datadog_dependency_enabled" {
6565
nullable = false
6666
}
6767

68+
variable "dd_readonly_root_filesystem" {
69+
description = "Datadog Agent container runs with read-only root filesystem enabled"
70+
type = bool
71+
default = false
72+
nullable = false
73+
}
74+
6875
variable "dd_health_check" {
6976
description = "Datadog Agent health check configuration"
7077
type = object({

smoke_tests/ecs_fargate/all-dd-disabled.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module "dd_task_all_dd_disabled" {
1717
dd_tags = "team:cont-p, owner:container-monitoring"
1818
dd_essential = true
1919
dd_is_datadog_dependency_enabled = false
20+
dd_readonly_root_filesystem = false
2021

2122
dd_environment = []
2223

smoke_tests/ecs_fargate/all-dd-inputs.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module "dd_task_all_dd_inputs" {
1717
dd_tags = "team:cont-p, owner:container-monitoring"
1818
dd_essential = true
1919
dd_is_datadog_dependency_enabled = true
20+
dd_readonly_root_filesystem = true
2021

2122
dd_environment = [
2223
{

smoke_tests/ecs_fargate/all-windows.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ module "dd_task_all_windows" {
1616
dd_site = var.dd_site
1717
dd_service = var.dd_service
1818

19+
dd_readonly_root_filesystem = false
20+
1921
dd_apm = {
2022
enabled = true
2123
}

smoke_tests/ecs_fargate/apm-dsd-tcp-udp.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ module "dd_task_apm_dsd_tcp_udp" {
1818
dd_tags = "team:cont-p, owner:container-monitoring"
1919
dd_essential = true
2020

21+
dd_readonly_root_filesystem = true
22+
2123
dd_dogstatsd = {
2224
enabled = true,
2325
socket_enabled = false,

smoke_tests/ecs_fargate/logging-only.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ module "dd_task_logging_only" {
1515
dd_service = var.dd_service
1616
dd_essential = true
1717

18+
dd_readonly_root_filesystem = false
19+
1820
dd_dogstatsd = {
1921
enabled = false,
2022
}

smoke_tests/ecs_fargate/ust-docker-labels.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module "dd_task_ust_docker_labels" {
2020
dd_essential = true
2121

2222
dd_is_datadog_dependency_enabled = true
23+
dd_readonly_root_filesystem = true
2324

2425
dd_log_collection = {
2526
enabled = true,

0 commit comments

Comments
 (0)