Skip to content

Commit fde865d

Browse files
authored
fix: Unknown ARNs and null value handling (#11)
* Updates to providing ARN resources that conditionally create other resources * Prevent entryPoint and linuxParam wipe on unsupported CWS containers * Input handling * Test updates
1 parent 1823330 commit fde865d

File tree

17 files changed

+621
-111
lines changed

17 files changed

+621
-111
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ module "datadog_ecs_fargate_task" {
1717
source = "DataDog/ecs-datadog/aws//modules/ecs_fargate"
1818
1919
# Datadog Configuration
20-
dd_api_key_secret_arn = "arn:aws:secretsmanager:us-east-1:0000000000:secret:example-secret"
20+
dd_api_key_secret = {
21+
arn = "arn:aws:secretsmanager:us-east-1:0000000000:secret:example-secret"
22+
}
2123
dd_tags = "team:cont-p, owner:container-monitoring"
2224
2325
# Task Configuration

examples/ecs_fargate/README.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ECS Fargate Example
22

3-
A simple ECS Fargate Task Definition with out of the box Datadog instrumentation.
3+
This example showcases a simple ECS Fargate Task Definition with out of the box Datadog instrumentation.
44

55
## Usage
66

@@ -16,3 +16,58 @@ terraform init
1616
terraform plan
1717
terraform apply
1818
```
19+
20+
### Example Module
21+
22+
```hcl
23+
module "datadog_ecs_fargate_task" {
24+
source = "DataDog/ecs-datadog/aws//modules/ecs_fargate"
25+
26+
# Configure Datadog
27+
dd_api_key = var.dd_api_key
28+
dd_site = var.dd_site
29+
dd_service = var.dd_service
30+
dd_tags = "team:cont-p, owner:container-monitoring"
31+
dd_essential = true
32+
dd_is_datadog_dependency_enabled = true
33+
34+
dd_dogstatsd = {
35+
enabled = true
36+
dogstatsd_cardinality = "high",
37+
origin_detection_enabled = true,
38+
}
39+
40+
dd_apm = {
41+
enabled = true,
42+
}
43+
44+
dd_log_collection = {
45+
enabled = true,
46+
}
47+
48+
# Configure Task Definition
49+
family = "datadog-terraform-app"
50+
container_definitions = jsonencode([
51+
{
52+
name = "datadog-dogstatsd-app",
53+
image = "ghcr.io/datadog/apps-dogstatsd:main",
54+
essential = false,
55+
},
56+
{
57+
name = "datadog-apm-app",
58+
image = "ghcr.io/datadog/apps-tracegen:main",
59+
essential = true,
60+
},
61+
])
62+
volumes = [
63+
{
64+
name = "app-volume"
65+
}
66+
]
67+
runtime_platform = {
68+
cpu_architecture = "ARM64"
69+
operating_system_family = "LINUX"
70+
}
71+
requires_compatibilities = ["FARGATE"]
72+
}
73+
```

examples/ecs_fargate/main.tf

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ module "datadog_ecs_fargate_task" {
1212

1313
# Configure Datadog
1414
dd_api_key = var.dd_api_key
15-
dd_api_key_secret_arn = var.dd_api_key_secret_arn
1615
dd_site = var.dd_site
1716
dd_service = var.dd_service
1817
dd_tags = "team:cont-p, owner:container-monitoring"
@@ -27,6 +26,7 @@ module "datadog_ecs_fargate_task" {
2726
]
2827

2928
dd_dogstatsd = {
29+
enabled = true
3030
dogstatsd_cardinality = "high",
3131
origin_detection_enabled = true,
3232
}
@@ -36,10 +36,7 @@ module "datadog_ecs_fargate_task" {
3636
}
3737

3838
dd_log_collection = {
39-
enabled = false,
40-
fluentbit_config = {
41-
is_log_router_dependency_enabled = true,
42-
}
39+
enabled = true,
4340
}
4441

4542
dd_cws = {
@@ -75,7 +72,6 @@ module "datadog_ecs_fargate_task" {
7572
name = "app-volume"
7673
}
7774
]
78-
inference_accelerator = null
7975
runtime_platform = {
8076
cpu_architecture = "ARM64"
8177
operating_system_family = "LINUX"

makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fmt:
2+
terraform fmt -recursive .

modules/ecs_fargate/README.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ module "ecs_fargate_task" {
6464

6565
This module exposes the same arguments available in the [aws_ecs_task_definition](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition) resource. However, because this module wraps that resource, it cannot support the exact same interface for configuration blocks defined by AWS. Instead, those blocks are represented as variables with nested attributes.
6666

67-
As a result, configuration blocks must now be assigned using an equals sign. For example, `runtime_platform { ... }` becomes `runtime_platform = { ... }`. Additionally, blocks that support multiple instances (such as volumes) should now be provided as a list of objects. Refer to the examples below for more details.
67+
As a result, configuration blocks must now be assigned using an equals sign. For example, `runtime_platform { ... }` becomes `runtime_platform = { ... }`. Additionally, blocks that support multiple instances (such as volumes) should now be provided as a list of objects.
68+
69+
One other minor difference is related to the way the `task_role_arn` and the `execution_role_arn` are provided. Instead of directly providing the value like `task_role_arn = "xxxxxx"`, you must provide the value wrapped in an object like `task_role = { arn = "xxxxxx" }`.
70+
71+
Refer to the examples below for more details.
6872

6973
#### aws_ecs_task_definition
7074

@@ -102,6 +106,8 @@ resource "aws_ecs_task_definition" "example" {
102106
cpu_architecture = "ARM64"
103107
operating_system_family = "LINUX"
104108
}
109+
110+
task_role_arn = "arn:aws:iam::123456789012:role/my-example-role"
105111
}
106112
```
107113

@@ -144,12 +150,18 @@ resource "datadog_ecs_fargate_task" "example" {
144150
}
145151
]
146152
147-
# Instead of creating a configuration block for `runtime_platforms`,
148-
# supply the definition directly to the argument `runtime_platforms`
153+
# Instead of creating a configuration block for `runtime_platform`,
154+
# supply the definition directly to the argument `runtime_platform`
149155
runtime_platform = {
150156
cpu_architecture = "ARM64"
151157
operating_system_family = "LINUX"
152158
}
159+
160+
# Instead of supplying the `task_role_arn` directly,
161+
# provide it into the `arn` field of the `task_role` object.
162+
task_role = {
163+
arn = "arn:aws:iam::123456789012:role/my-example-role"
164+
}
153165
}
154166
```
155167

@@ -209,33 +221,35 @@ No modules.
209221
| Name | Description | Type | Default | Required |
210222
|------|-------------|------|---------|:--------:|
211223
| <a name="input_container_definitions"></a> [container\_definitions](#input\_container\_definitions) | A list of valid [container definitions](http://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html). Please note that you should only provide values that are part of the container definition document | `any` | n/a | yes |
212-
| <a name="input_cpu"></a> [cpu](#input\_cpu) | Number of cpu units used by the task. If the `requires_compatibilities` is `FARGATE` this field is required | `number` | `512` | no |
224+
| <a name="input_cpu"></a> [cpu](#input\_cpu) | Number of cpu units used by the task. If the `requires_compatibilities` is `FARGATE` this field is required | `number` | `256` | no |
213225
| <a name="input_dd_api_key"></a> [dd\_api\_key](#input\_dd\_api\_key) | Datadog API Key | `string` | `null` | no |
214-
| <a name="input_dd_api_key_secret_arn"></a> [dd\_api\_key\_secret\_arn](#input\_dd\_api\_key\_secret\_arn) | Datadog API Key Secret ARN | `string` | `null` | no |
226+
| <a name="input_dd_api_key_secret"></a> [dd\_api\_key\_secret](#input\_dd\_api\_key\_secret) | Datadog API Key Secret ARN | <pre>object({<br/> arn = string<br/> })</pre> | `null` | no |
215227
| <a name="input_dd_apm"></a> [dd\_apm](#input\_dd\_apm) | Configuration for Datadog APM | <pre>object({<br/> enabled = optional(bool, true)<br/> socket_enabled = optional(bool, true)<br/> })</pre> | <pre>{<br/> "enabled": true,<br/> "socket_enabled": true<br/>}</pre> | no |
216228
| <a name="input_dd_checks_cardinality"></a> [dd\_checks\_cardinality](#input\_dd\_checks\_cardinality) | Datadog Agent checks cardinality | `string` | `null` | no |
217229
| <a name="input_dd_cluster_name"></a> [dd\_cluster\_name](#input\_dd\_cluster\_name) | Datadog cluster name | `string` | `null` | no |
218-
| <a name="input_dd_cws"></a> [dd\_cws](#input\_dd\_cws) | Configuration for Datadog Cloud Workload Security (CWS) | <pre>object({<br/> enabled = bool<br/> cpu = optional(number)<br/> memory_limit_mib = optional(number)<br/> })</pre> | <pre>{<br/> "enabled": false<br/>}</pre> | no |
230+
| <a name="input_dd_cpu"></a> [dd\_cpu](#input\_dd\_cpu) | Datadog Agent container CPU units | `number` | `null` | no |
231+
| <a name="input_dd_cws"></a> [dd\_cws](#input\_dd\_cws) | Configuration for Datadog Cloud Workload Security (CWS) | <pre>object({<br/> enabled = optional(bool, false)<br/> cpu = optional(number)<br/> memory_limit_mib = optional(number)<br/> })</pre> | <pre>{<br/> "enabled": false<br/>}</pre> | no |
219232
| <a name="input_dd_dogstatsd"></a> [dd\_dogstatsd](#input\_dd\_dogstatsd) | Configuration for Datadog DogStatsD | <pre>object({<br/> enabled = optional(bool, true)<br/> origin_detection_enabled = optional(bool, true)<br/> dogstatsd_cardinality = optional(string, "orchestrator")<br/> socket_enabled = optional(bool, true)<br/> })</pre> | <pre>{<br/> "dogstatsd_cardinality": "orchestrator",<br/> "enabled": true,<br/> "origin_detection_enabled": true,<br/> "socket_enabled": true<br/>}</pre> | no |
220233
| <a name="input_dd_env"></a> [dd\_env](#input\_dd\_env) | The task environment name. Used for tagging (UST) | `string` | `null` | no |
221-
| <a name="input_dd_environment"></a> [dd\_environment](#input\_dd\_environment) | Datadog Agent container environment variables. Highest precedence and overwrites other environment variables defined by the module | `list(map(string))` | <pre>[<br/> {}<br/>]</pre> | no |
234+
| <a name="input_dd_environment"></a> [dd\_environment](#input\_dd\_environment) | Datadog Agent container environment variables. Highest precedence and overwrites other environment variables defined by the module. For example, `dd_environment = [ { name = 'DD_VAR', value = 'DD_VAL' } ]` | `list(map(string))` | <pre>[<br/> {}<br/>]</pre> | no |
222235
| <a name="input_dd_essential"></a> [dd\_essential](#input\_dd\_essential) | Whether the Datadog Agent container is essential | `bool` | `false` | no |
223236
| <a name="input_dd_health_check"></a> [dd\_health\_check](#input\_dd\_health\_check) | Datadog Agent health check configuration | <pre>object({<br/> command = optional(list(string))<br/> interval = optional(number)<br/> retries = optional(number)<br/> start_period = optional(number)<br/> timeout = optional(number)<br/> })</pre> | <pre>{<br/> "command": [<br/> "CMD-SHELL",<br/> "/probe.sh"<br/> ],<br/> "interval": 15,<br/> "retries": 3,<br/> "start_period": 60,<br/> "timeout": 5<br/>}</pre> | no |
224237
| <a name="input_dd_image_version"></a> [dd\_image\_version](#input\_dd\_image\_version) | Datadog Agent image version | `string` | `"latest"` | no |
225238
| <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 |
226239
| <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/> 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/> 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/> }))<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 |
240+
| <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 |
227241
| <a name="input_dd_registry"></a> [dd\_registry](#input\_dd\_registry) | Datadog Agent image registry | `string` | `"public.ecr.aws/datadog/agent"` | no |
228242
| <a name="input_dd_service"></a> [dd\_service](#input\_dd\_service) | The task service name. Used for tagging (UST) | `string` | `null` | no |
229243
| <a name="input_dd_site"></a> [dd\_site](#input\_dd\_site) | Datadog Site | `string` | `"datadoghq.com"` | no |
230244
| <a name="input_dd_tags"></a> [dd\_tags](#input\_dd\_tags) | Datadog Agent global tags (eg. `key1:value1, key2:value2`) | `string` | `null` | no |
231245
| <a name="input_dd_version"></a> [dd\_version](#input\_dd\_version) | The task version name. Used for tagging (UST) | `string` | `null` | no |
232246
| <a name="input_enable_fault_injection"></a> [enable\_fault\_injection](#input\_enable\_fault\_injection) | Enables fault injection and allows for fault injection requests to be accepted from the task's containers | `bool` | `false` | no |
233247
| <a name="input_ephemeral_storage"></a> [ephemeral\_storage](#input\_ephemeral\_storage) | The amount of ephemeral storage to allocate for the task. This parameter is used to expand the total amount of ephemeral storage available, beyond the default amount, for tasks hosted on AWS Fargate | <pre>object({<br/> size_in_gib = number<br/> })</pre> | `null` | no |
234-
| <a name="input_execution_role_arn"></a> [execution\_role\_arn](#input\_execution\_role\_arn) | ARN of the task execution role that the Amazon ECS container agent and the Docker daemon can assume | `string` | `null` | no |
248+
| <a name="input_execution_role"></a> [execution\_role](#input\_execution\_role) | ARN of the task execution role that the Amazon ECS container agent and the Docker daemon can assume | <pre>object({<br/> arn = string<br/> })</pre> | `null` | no |
235249
| <a name="input_family"></a> [family](#input\_family) | A unique name for your task definition | `string` | n/a | yes |
236250
| <a name="input_inference_accelerator"></a> [inference\_accelerator](#input\_inference\_accelerator) | Configuration list with Inference Accelerators settings | <pre>list(object({<br/> device_name = string<br/> device_type = string<br/> }))</pre> | `[]` | no |
237251
| <a name="input_ipc_mode"></a> [ipc\_mode](#input\_ipc\_mode) | IPC resource namespace to be used for the containers in the task The valid values are `host`, `task`, and `none` | `string` | `null` | no |
238-
| <a name="input_memory"></a> [memory](#input\_memory) | Amount (in MiB) of memory used by the task. If the `requires_compatibilities` is `FARGATE` this field is required | `number` | `1024` | no |
252+
| <a name="input_memory"></a> [memory](#input\_memory) | Amount (in MiB) of memory used by the task. If the `requires_compatibilities` is `FARGATE` this field is required | `number` | `512` | no |
239253
| <a name="input_network_mode"></a> [network\_mode](#input\_network\_mode) | Docker networking mode to use for the containers in the task. Valid values are `none`, `bridge`, `awsvpc`, and `host` | `string` | `"awsvpc"` | no |
240254
| <a name="input_pid_mode"></a> [pid\_mode](#input\_pid\_mode) | Process namespace to use for the containers in the task. The valid values are `host` and `task` | `string` | `"task"` | no |
241255
| <a name="input_placement_constraints"></a> [placement\_constraints](#input\_placement\_constraints) | Configuration list for rules that are taken into consideration during task placement (up to max of 10) | <pre>list(object({<br/> type = string<br/> expression = string<br/> }))</pre> | `[]` | no |
@@ -244,7 +258,7 @@ No modules.
244258
| <a name="input_runtime_platform"></a> [runtime\_platform](#input\_runtime\_platform) | Configuration for `runtime_platform` that containers in your task may use | <pre>object({<br/> cpu_architecture = optional(string, "LINUX")<br/> operating_system_family = optional(string, "X86_64")<br/> })</pre> | <pre>{<br/> "cpu_architecture": "X86_64",<br/> "operating_system_family": "LINUX"<br/>}</pre> | no |
245259
| <a name="input_skip_destroy"></a> [skip\_destroy](#input\_skip\_destroy) | Whether to retain the old revision when the resource is destroyed or replacement is necessary | `bool` | `false` | no |
246260
| <a name="input_tags"></a> [tags](#input\_tags) | A map of additional tags to add to the task definition/set created | `map(string)` | `null` | no |
247-
| <a name="input_task_role_arn"></a> [task\_role\_arn](#input\_task\_role\_arn) | The ARN of the IAM role that allows your Amazon ECS container task to make calls to other AWS services | `string` | `null` | no |
261+
| <a name="input_task_role"></a> [task\_role](#input\_task\_role) | The ARN of the IAM role that allows your Amazon ECS container task to make calls to other AWS services | <pre>object({<br/> arn = string<br/> })</pre> | `null` | no |
248262
| <a name="input_track_latest"></a> [track\_latest](#input\_track\_latest) | Whether should track latest ACTIVE task definition on AWS or the one created with the resource stored in state | `bool` | `false` | no |
249263
| <a name="input_volumes"></a> [volumes](#input\_volumes) | A list of volume definitions that containers in your task may use | <pre>list(object({<br/> name = string<br/> host_path = optional(string)<br/> configure_at_launch = optional(bool)<br/><br/> docker_volume_configuration = optional(object({<br/> autoprovision = optional(bool)<br/> driver = optional(string)<br/> driver_opts = optional(map(any))<br/> labels = optional(map(any))<br/> scope = optional(string)<br/> }))<br/><br/> efs_volume_configuration = optional(object({<br/> file_system_id = string<br/> root_directory = optional(string)<br/> transit_encryption = optional(string)<br/> transit_encryption_port = optional(number)<br/> authorization_config = optional(object({<br/> access_point_id = optional(string)<br/> iam = optional(string)<br/> }))<br/> }))<br/><br/> fsx_windows_file_server_volume_configuration = optional(object({<br/> file_system_id = string<br/> root_directory = optional(string)<br/> authorization_config = optional(object({<br/> credentials_parameter = string<br/> domain = string<br/> }))<br/> }))<br/> }))</pre> | `[]` | no |
250264

0 commit comments

Comments
 (0)