-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.tf
151 lines (127 loc) · 5.1 KB
/
main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
resource "aws_ecs_task_definition" "task" {
family = "${var.cluster_name}-${var.service_name}"
cpu = local.use_fargate ? var.cpu : null
memory = local.use_fargate ? var.memory : null
execution_role_arn = local.use_fargate ? aws_iam_role.task-execution-role.arn : null
network_mode = local.use_fargate ? "awsvpc" : "bridge"
container_definitions = jsonencode([for s in concat([
{
name = var.service_name
image = var.image
cpu = var.cpu
essential = var.essential
links = var.links
memory = var.memory
memoryReservation = var.memory_reservation
mountPoints = local.task_def_all_mount_points
volumesFrom = []
linuxParameters = {
initProcessEnabled = var.init_process_enabled
}
readonlyRootFilesystem = var.readonlyRootFilesystem
user = var.user != "" ? var.user : null
}
], var.additional_container_definitions) : merge(s, {
environment = [for k in sort(keys(var.environment)) : { "name" : k, "value" : var.environment[k] }]
# leverage the new terraform syntax and override the awslogs-stream-prefix
logConfiguration = merge(local.log_configuration,
local.log_configuration["logDriver"] == "awslogs" && local.log_configuration["options"] != null ? {
options = merge(local.log_configuration["options"], { "awslogs-stream-prefix" = s.name })
} : {}
)
# load balancer the local.load_balancer_container_name
portMappings = local.balanced && local.load_balancer_container_name == s.name ? local.port_mappings : []
})])
requires_compatibilities = [local.use_fargate ? "FARGATE" : "EC2"]
dynamic "volume" {
for_each = local.task_def_efs_volumes
content {
name = volume.value.name
efs_volume_configuration {
file_system_id = volume.value.efs_id
root_directory = volume.value.root_directory
}
}
}
task_role_arn = var.task_role_arn
# the /tmp volume is needed if the root fs is readonly
# tmpfs takes precious memory, so it's easier to create a volume
dynamic "volume" {
for_each = var.readonlyRootFilesystem ? [{}] : []
content {
name = "tmp"
docker_volume_configuration {
scope = "task"
}
}
}
}
resource "aws_ecs_service" "service" {
name = var.service_name
cluster = var.cluster_name
task_definition = "${aws_ecs_task_definition.task.family}:${aws_ecs_task_definition.task.revision}"
desired_count = var.desired_count
deployment_minimum_healthy_percent = var.deployment_minimum_healthy_percent
deployment_maximum_percent = var.deployment_maximum_percent
enable_execute_command = var.enable_execute_command
// can't use this for Fargate
dynamic "ordered_placement_strategy" {
for_each = !local.use_fargate ? [
{ type = "spread", field = "attribute:ecs.availability-zone" },
{ type = "spread", field = "instanceId" },
] : []
iterator = each
content {
type = each.value.type
field = each.value.field
}
}
dynamic "load_balancer" {
for_each = local.balanced ? zipmap(local.target_group_arns, var.port_mappings) : {}
content {
target_group_arn = load_balancer.key
container_name = local.load_balancer_container_name
container_port = load_balancer.value.containerPort
}
}
// Fargate-specifics
// For launch_type we use capacity providers in case of Fargate
// to utilise Fargate_spot if we need to
launch_type = local.use_fargate || var.use_default_capacity_provider ? null : "EC2"
dynamic "capacity_provider_strategy" {
for_each = local.use_fargate ? [{}] : []
content {
capacity_provider = var.fargate_spot ? "FARGATE_SPOT" : "FARGATE"
weight = 100
}
}
dynamic "network_configuration" {
for_each = local.use_fargate ? [{}] : []
content {
subnets = var.subnet_ids
security_groups = var.security_groups
// hardcode it for now
// otherwise it requires private links everywhere of NAT
assign_public_ip = true
}
}
lifecycle {
// unfortunately we can't ignore it conditionally,
// which would be nice if we want to manipulate capacity provider strategies
// after creating the service
ignore_changes = [capacity_provider_strategy]
}
}
locals {
task_def_ro_mount_points = var.readonlyRootFilesystem ? [{ sourceVolume = "tmp", containerPath = "/tmp" }] : []
task_def_efs_volumes = [for efs_vol in var.efs_volumes : {
name = "${var.cluster_name}-${efs_vol.efs_id}"
efs_id = efs_vol.efs_id
root_directory = lookup(efs_vol, "root_dir", "/mnt/efs")
}]
task_def_efs_mount_points = [for efs_vol in var.efs_volumes : {
sourceVolume = "${var.cluster_name}-${efs_vol.efs_id}"
containerPath = lookup(efs_vol, "container_path", "/private_storage")
}]
task_def_all_mount_points = concat(local.task_def_ro_mount_points, local.task_def_efs_mount_points)
}