Opinionated.tf/docker-service/service.tf

168 lines
4.3 KiB
Terraform
Raw Normal View History

2024-07-29 19:28:08 +00:00
resource "docker_volume" "volume" {
for_each = var.volumes
name = lower("${var.stack_name}-${replace(each.key, "/", "-")}")
}
data "docker_registry_image" "image" {
name = var.image
}
resource "docker_service" "instance" {
# The name of the service is the stack name and the service name combined
name = "${var.stack_name}-${var.service_name}"
# Define the task spec
task_spec {
container_spec {
image = "${data.docker_registry_image.image.name}@${data.docker_registry_image.image.sha256_digest}"
command = var.command
env = var.environment_variables
# Mount all the created volumes
dynamic "mounts" {
for_each = var.volumes
content {
target = mounts.value
source = docker_volume.volume[mounts.key].id
type = "volume"
}
}
2024-07-31 12:26:17 +00:00
dynamic "mounts" {
for_each = var.mounts
content {
target = mounts.value
source = mounts.key
type = "bind"
}
}
dynamic "configs" {
for_each = var.configs
content {
config_id = docker_config.config[configs.key].id
config_name = docker_config.config[configs.key].name
file_name = configs.value.path
}
}
2024-07-29 19:28:08 +00:00
# Apply the healthcheck
dynamic "healthcheck" {
for_each = var.healthcheck != null ? [var.healthcheck] : []
content {
test = healthcheck.value
interval = "10s"
timeout = "3s"
retries = 0
start_period = "0s"
}
}
# Container labels
labels {
label = "com.docker.stack.namespace"
value = var.stack_name
}
}
# Apply the networks
dynamic "networks_advanced" {
for_each = var.networks
content {
name = networks_advanced.value
}
}
2024-07-30 02:08:50 +00:00
# Apply restart policy
2024-07-29 19:28:08 +00:00
restart_policy {
2024-07-30 02:08:50 +00:00
condition = var.one_shot ? "none" : "any"
2024-07-29 19:28:08 +00:00
delay = "0s"
window = "0s"
max_attempts = 0
}
placement {
constraints = var.placement_constraints
platforms {
architecture = var.processor_architecture
os = var.operating_system
}
}
}
# Global deploy
dynamic "mode" {
for_each = var.global ? [{}] : []
content {
global = true
}
}
# Or replicated deploy
dynamic "mode" {
for_each = !var.global ? [{}] : []
content {
replicated {
replicas = var.parallelism
}
}
}
# Behaviour regarding startup and delaying/waiting. Not possible in global deploy mode.
dynamic "converge_config" {
for_each = !var.global ? [{}] : []
content {
delay = "5s"
timeout = "2m"
}
}
# How to handle updates/re-deployments
update_config {
# Parallelism must be the size of the count of instances, divided by the number of update waves
# with a minimum of 1.
# Confusingly, the max() function gives you the largest number of the two, so if the parallelism is 0, 1 will be greater.
2024-08-01 17:12:28 +00:00
parallelism = max(1, ceil(var.parallelism / var.update_waves))
# The order of stopping and starting containers.
# Some containers can be run while the previous is still running (e.g web servers, anything ephemeral)
# Some cannot have more than 1 instance running at the same time (e.g databases, anything concrete)
2024-08-01 17:12:28 +00:00
order = var.start_first ? "start-first" : "stop-first"
2024-07-29 19:28:08 +00:00
}
# Ports and such
endpoint_spec {
dynamic "ports" {
for_each = var.ports
content {
2024-07-31 14:13:06 +00:00
target_port = ports.value.container
published_port = ports.value.host
protocol = ports.value.protocol
2024-07-29 19:28:08 +00:00
publish_mode = "ingress"
}
}
}
# Service Labels
labels {
label = "com.docker.stack.namespace"
value = var.stack_name
}
labels {
label = "com.docker.stack.image"
value = var.image
}
2024-07-31 12:26:17 +00:00
}
resource "docker_config" "config" {
for_each = var.configs
data = base64encode(each.value.contents)
name = join("-", concat(each.value.name_prefix, [substr(sha1(each.value.contents), 0, 7)]))
lifecycle {
create_before_destroy = true
}
}
resource "local_file" "config" {
for_each = var.configs
content = each.value.contents
filename = "${path.root}/.debug/docker-service/${var.stack_name}-${var.service_name}/configs/${each.key}"
2024-07-29 19:28:08 +00:00
}