Skip to content

Commit d0eeb03

Browse files
committed
Allow define one optional volume
For some cases and workloads we need to pass some modules to the task definition. The volumes are passed as a list of maps to the ecs_task_resource[1]. But the current syntax of terraform does not allow consume this value directly from a variable. Trying to do so, we hit the issues described in [2] and [3] (pending to report a specific bug). But we found out that it works if we build the map structure directly within the resource, and we use interpolation to consume the values of the map. Meanwhile the terraform project does not provide a definitive solution, we will implement the following workaround: - The module will receive configuration for one unique module, being the default a empty map {} - If the map is empty, a dummy volume will be passed as `name=dummy` and `host_path=/tmp/dummy_volume` This would cover our specific case in the short term, and can be later easily adapted to use a optional list of volumes. [1] https://www.terraform.io/docs/providers/aws/r/ecs_task_definition.html#volume [2] hashicorp/terraform#10407 [3] hashicorp/terraform#7705 (comment)
1 parent 7e12816 commit d0eeb03

File tree

5 files changed

+61
-11
lines changed

5 files changed

+61
-11
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This module creates a basic ECS Task Definition.
2424
* `family` - the name of the task definition. For ECS services it is recommended to use the same name as for the service, and for that name to consist of the environment name (e.g. "live"), the comonent name (e.g. "foobar-service"), and an optional suffix (if an environment has multiple services for the component running - e.g. in a multi-tenant setup), separated by hyphens.
2525
* `container_definitions` - list of strings. Each string should be a JSON document describing a single container definition - see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html.
2626
* `task_role_arn` - The Amazon Resource Name for an IAM role for the task.
27+
* `volume` - Volume block map with 'name' and 'host_path'. 'name': The name of the volume as is referenced in the sourceVolume. 'host_path' The path on the host container instance that is presented to the container.
2728

2829
### Outputs
2930

main.tf

+5
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@ resource "aws_ecs_task_definition" "taskdef" {
22
family = "${var.family}"
33
container_definitions = "[${join(",", var.container_definitions)}]"
44
task_role_arn = "${var.task_role_arn}"
5+
6+
volume = {
7+
name = "${lookup(var.volume, "name", "dummy")}",
8+
host_path = "${lookup(var.volume, "host_path", "/tmp/dummy_volume")}"
9+
}
510
}

test/infra/main.tf

+7
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,18 @@ variable "task_role_arn_param" {
1616
default = ""
1717
}
1818

19+
variable "task_volume_param" {
20+
description = "Allow the test to pass this in"
21+
type = "map"
22+
default = {}
23+
}
24+
1925
module "taskdef" {
2026
source = "../.."
2127

2228
family = "tf_ecs_taskdef_test_family"
2329
task_role_arn = "${var.task_role_arn_param}"
30+
volume = "${var.task_volume_param}"
2431
container_definitions = [
2532
<<END
2633
{

test/test_taskdef.py

+42-11
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ def test_create_taskdef(self):
1919
'-no-color',
2020
'test/infra'
2121
]).decode('utf-8')
22+
print(output)
2223

2324
assert dedent("""
2425
+ module.taskdef.aws_ecs_task_definition.taskdef
25-
arn: "<computed>"
26-
container_definitions: "a173db30ec08bc3c9ca77b5797aeae40987c1ef7"
27-
family: "tf_ecs_taskdef_test_family"
28-
network_mode: "<computed>"
29-
revision: "<computed>"
26+
arn: "<computed>"
27+
container_definitions: "a173db30ec08bc3c9ca77b5797aeae40987c1ef7"
28+
family: "tf_ecs_taskdef_test_family"
29+
network_mode: "<computed>"
30+
revision: "<computed>"
31+
volume.#: "1"
32+
volume.3039886685.host_path: "/tmp/dummy_volume"
33+
volume.3039886685.name: "dummy"
3034
Plan: 1 to add, 0 to change, 0 to destroy.
3135
""").strip() in output
3236

@@ -41,11 +45,38 @@ def test_task_role_arn_is_included(self):
4145

4246
assert dedent("""
4347
+ module.taskdef.aws_ecs_task_definition.taskdef
44-
arn: "<computed>"
45-
container_definitions: "a173db30ec08bc3c9ca77b5797aeae40987c1ef7"
46-
family: "tf_ecs_taskdef_test_family"
47-
network_mode: "<computed>"
48-
revision: "<computed>"
49-
task_role_arn: "arn::iam:123"
48+
arn: "<computed>"
49+
container_definitions: "a173db30ec08bc3c9ca77b5797aeae40987c1ef7"
50+
family: "tf_ecs_taskdef_test_family"
51+
network_mode: "<computed>"
52+
revision: "<computed>"
53+
task_role_arn: "arn::iam:123"
54+
volume.#: "1"
55+
volume.3039886685.host_path: "/tmp/dummy_volume"
56+
volume.3039886685.name: "dummy"
57+
Plan: 1 to add, 0 to change, 0 to destroy.
58+
""").strip() in output
59+
60+
def test_task_volume_is_included(self):
61+
output = check_output([
62+
'terraform',
63+
'plan',
64+
'-var', 'task_volume_param={name="data_volume",host_path="/mnt/data"}',
65+
'-no-color',
66+
'test/infra'
67+
]).decode('utf-8')
68+
69+
print(output)
70+
71+
assert dedent("""
72+
+ module.taskdef.aws_ecs_task_definition.taskdef
73+
arn: "<computed>"
74+
container_definitions: "a173db30ec08bc3c9ca77b5797aeae40987c1ef7"
75+
family: "tf_ecs_taskdef_test_family"
76+
network_mode: "<computed>"
77+
revision: "<computed>"
78+
volume.#: "1"
79+
volume.27251535.host_path: "/mnt/data"
80+
volume.27251535.name: "data_volume"
5081
Plan: 1 to add, 0 to change, 0 to destroy.
5182
""").strip() in output

variables.tf

+6
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ variable "task_role_arn" {
1313
type = "string"
1414
default = ""
1515
}
16+
17+
variable "volume" {
18+
description = "Volume block map with 'name' and 'host_path'. 'name': The name of the volume as is referenced in the sourceVolume. 'host_path' The path on the host container instance that is presented to the container."
19+
type = "map"
20+
default = {}
21+
}

0 commit comments

Comments
 (0)