-
Notifications
You must be signed in to change notification settings - Fork 29
/
main.tf
160 lines (137 loc) · 5.98 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
152
153
154
155
156
157
158
159
160
/* ========================================================================== */
/* CONFIGURATION OPTIONS / ENVIRONMENT VARIABLES */
/* ========================================================================== */
locals {
# Parse container definition and exclude fields that are better defined as
# environment variables (see below).
container = {
for k, v in var.container : k => v if !contains(["image", "container_name", "command"], k)
}
# Define environment variables that will be written to `/var/app/.env` and
# made available to all running services, including Docker Compose and systemd.
# The list below is not exhaustive, refer to the Docker documentation for additional
# configuration options (https://docs.docker.com/compose/reference/envvars/)
environment = merge({
DOMAIN = var.domain
LETSENCRYPT_EMAIL = var.email
LETSENCRYPT_SERVER = var.letsencrypt_staging ? "https://acme-staging-v02.api.letsencrypt.org/directory" : null
IMAGE_NAME = try(split(":", var.container.image)[0], null)
IMAGE_TAG = try(split(":", var.container.image)[1], "latest")
CONTAINER_NAME = lookup(var.container, "container_name", null)
CONTAINER_COMMAND = lookup(var.container, "command", null)
CONTAINER_PORT = lookup(var.container, "port", null)
DOCKER_NETWORK = "web"
DOCKER_LOG_DRIVER = null
COMPOSE_DOCKER_IMAGE = var.docker_compose_image
COMPOSE_DOCKER_TAG = var.docker_compose_tag
TRAEFIK_ENABLED = null
TRAEFIK_IMAGE_TAG = null
TRAEFIK_LOG_LEVEL = null
TRAEFIK_API_DASHBOARD = null
TRAEFIK_PASSWD_FILE = null
TRAEFIK_EXPOSED_BY_DEFAULT = null
TRAEFIK_OPS_PORT = null
WEBHOOK_URL_PREFIX = var.enable_webhook ? "hooks" : null
WEBHOOK_HTTP_METHOD = var.enable_webhook ? "PATCH" : null
}, var.env)
}
/* ========================================================================== */
/* DOCKER COMPOSE FILE(S) */
/* ========================================================================== */
locals {
template_dir = "${path.module}/templates"
file_regex = "(?P<filename>docker-compose(?:\\.(?P<name>.*?))?\\.ya?ml)"
# Merge the container definition provided by the user with the default template.
# The resulting object should match the schema expected by Docker Compose.
docker_compose_template_yaml = file("${local.template_dir}/docker-compose.default.yaml")
docker_compose_template = yamldecode(local.docker_compose_template_yaml)
docker_compose = {
version = "3.3"
services = {
app = merge(local.docker_compose_template.services.app, local.container, {
for key, val in local.docker_compose_template.services.app : key =>
can(tolist(val)) && contains(keys(local.container), key)
? try(setunion(val, lookup(local.container, key, [])), val)
: lookup(local.container, key, val)
})
}
networks = {
default = {
external = {
name = "$${DOCKER_NETWORK}"
}
}
}
}
docker_compose_yaml = yamlencode(local.docker_compose)
}
/* ========================================================================== */
/* CLOUD-INIT CONFIG */
/* ========================================================================== */
// Collate all files to be copied to the server on start-up
locals {
files = concat(
[
{
filename = ".env"
content = base64encode(join("\n", [for k, v in local.environment : "${k}=${v}" if v != null]))
},
{
filename = "docker-compose.traefik.yaml"
content = filebase64("${local.template_dir}/docker-compose.traefik.yaml")
},
],
# Configuration and scripts relating to the webhook service and its endpoints (only if enabled).
var.enable_webhook ? [
{ filename = "docker-compose.webhook.yaml"
content = filebase64("${local.template_dir}/docker-compose.webhook.yaml") },
{
filename = ".webhook/hooks.json"
content = filebase64("${local.template_dir}/webook/hooks.json")
},
{
filename = ".webhook/update-env.sh"
content = filebase64("${local.template_dir}/webook/update-env.sh")
}
] : [],
# User-provided docker-compose*.yaml files.
# If no docker-compose.yaml files are present, one will be generated
# automatically using the default template and merged with the values specified
# in `var.container`.
coalescelist(
[for f in var.files : f if can(regex(local.file_regex, f.filename))],
[{ filename = "docker-compose.yaml", content = base64encode(local.docker_compose_yaml) }]
),
# Other user files
[for f in var.files : f if !can(regex(local.file_regex, f.filename))]
)
# From the list above, identify all docker-compose*.yaml files.
# This list will be used to generate separate systemd unit files for each service.
docker_compose_files = [
for f in local.files : merge(regex(local.file_regex, f.filename), f)
if can(regex(local.file_regex, f.filename))
]
}
// Generate cloud-init config
data "cloudinit_config" "config" {
gzip = false
base64_encode = false
part {
filename = "cloud-init.yaml"
merge_type = "list(append)+dict(no_replace,recurse_list)+str()"
content_type = "text/cloud-config"
content = templatefile("${local.template_dir}/cloud-config.yaml", {
files = local.files
docker_compose_files = local.docker_compose_files
})
}
# Add any additional cloud-init configuration or scripts provided by the user
dynamic "part" {
for_each = var.cloudinit_part
content {
merge_type = "list(append)+dict(no_replace,recurse_list)+str()"
content_type = part.value.content_type
content = part.value.content
}
}
}