Everything moved again.
This commit is contained in:
parent
1f7947dd95
commit
cb74c92781
20 changed files with 258 additions and 72 deletions
docker
config
network
service
volume
products/forgejo/actions-runner
9
docker/config/config.tf
Normal file
9
docker/config/config.tf
Normal file
|
@ -0,0 +1,9 @@
|
|||
resource "docker_config" "config" {
|
||||
name = local.config_name
|
||||
data = base64encode(var.value)
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
}
|
||||
}
|
||||
|
5
docker/config/debug.tf
Normal file
5
docker/config/debug.tf
Normal file
|
@ -0,0 +1,5 @@
|
|||
resource "local_file" "config" {
|
||||
count = var.debug ? 1 : 0
|
||||
content = var.value
|
||||
filename = "${path.root}/.debug/docker/${var.stack_name}/configs/${local.file_name}"
|
||||
}
|
22
docker/config/inputs.tf
Normal file
22
docker/config/inputs.tf
Normal file
|
@ -0,0 +1,22 @@
|
|||
variable "stack_name" {
|
||||
type = string
|
||||
description = "The name of the stack to deploy the service to."
|
||||
}
|
||||
variable "name" {
|
||||
type = string
|
||||
description = "The name of the docker config."
|
||||
}
|
||||
variable "value" {
|
||||
type = string
|
||||
description = "The value of the docker config."
|
||||
}
|
||||
variable "labels" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "A map of labels to apply to the service"
|
||||
}
|
||||
variable "debug" {
|
||||
type = bool
|
||||
default = true
|
||||
description = "Emit debug files in .debug directory"
|
||||
}
|
24
docker/config/locals.tf
Normal file
24
docker/config/locals.tf
Normal file
|
@ -0,0 +1,24 @@
|
|||
locals {
|
||||
path = var.name
|
||||
file_name = element(split("/", local.path), length(split("/", local.path)) - 1)
|
||||
// Name can be 64 bytes long, including a null byte seemingly, limiting the length to 63.
|
||||
// The hash is 7 bytes long. We lose 2 more bytes to the dashes. So we have 54 bytes left.
|
||||
// I will share that into 20 bytes for the stack name, remaining bytes for the config name
|
||||
config_name = join("-", [
|
||||
substr(var.stack_name, 0, 20),
|
||||
substr(local.file_name, 0, 64 - 1 - 7 - 2 - 20),
|
||||
substr(sha1(var.value), 0, 7)
|
||||
])
|
||||
|
||||
// define config labels
|
||||
labels = merge(var.labels, {
|
||||
"com.docker.stack.namespace" = var.stack_name
|
||||
"ooo.grey.config.stack" = var.stack_name
|
||||
#"ooo.grey.config.created" = timestamp()
|
||||
"ooo.grey.config.bytes" = length(var.value)
|
||||
"ooo.grey.config.name" = local.config_name
|
||||
"ooo.grey.config.hash" = sha1(var.value)
|
||||
"ooo.grey.config.file" = local.file_name
|
||||
"ooo.grey.config.path" = local.path
|
||||
})
|
||||
}
|
6
docker/config/outputs.tf
Normal file
6
docker/config/outputs.tf
Normal file
|
@ -0,0 +1,6 @@
|
|||
output "id" {
|
||||
value = docker_config.config.id
|
||||
}
|
||||
output "name" {
|
||||
value = docker_config.config.name
|
||||
}
|
16
docker/config/terraform.tf
Normal file
16
docker/config/terraform.tf
Normal file
|
@ -0,0 +1,16 @@
|
|||
terraform {
|
||||
required_version = "~> 1.6"
|
||||
|
||||
required_providers {
|
||||
docker = {
|
||||
source = "kreuzwerker/docker"
|
||||
version = "~>3.0"
|
||||
}
|
||||
local = {
|
||||
source = "hashicorp/local"
|
||||
version = "~>2.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,3 +1,9 @@
|
|||
variable "stack_name" {
|
||||
type = string
|
||||
}
|
||||
description = "The name of the collective stack"
|
||||
type = string
|
||||
}
|
||||
variable "labels" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "A map of labels to apply to the service"
|
||||
}
|
||||
|
|
9
docker/network/locals.tf
Normal file
9
docker/network/locals.tf
Normal file
|
@ -0,0 +1,9 @@
|
|||
locals {
|
||||
network_name = var.stack_name
|
||||
labels = merge(var.labels, {
|
||||
"com.docker.stack.namespace" = var.stack_name
|
||||
"ooo.grey.network.stack" = var.stack_name
|
||||
"ooo.grey.network.name" = local.network_name
|
||||
#"ooo.grey.network.created" = timestamp()
|
||||
})
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
resource "docker_network" "instance" {
|
||||
name = var.stack_name
|
||||
name = local.network_name
|
||||
driver = "overlay"
|
||||
labels {
|
||||
label = "com.docker.stack.namespace"
|
||||
value = var.stack_name
|
||||
|
||||
# Attach labels
|
||||
dynamic "labels" {
|
||||
for_each = local.labels
|
||||
content {
|
||||
label = labels.key
|
||||
value = labels.value
|
||||
}
|
||||
}
|
||||
}
|
7
docker/service/config.tf
Normal file
7
docker/service/config.tf
Normal file
|
@ -0,0 +1,7 @@
|
|||
module "config" {
|
||||
for_each = var.configs
|
||||
source = "../../docker/config"
|
||||
stack_name = var.stack_name
|
||||
name = each.key
|
||||
value = each.value
|
||||
}
|
|
@ -5,6 +5,15 @@ variable "command" {
|
|||
type = list(string)
|
||||
default = null
|
||||
}
|
||||
variable "restart_policy" {
|
||||
type = string
|
||||
default = "any"
|
||||
description = "The restart policy for the service."
|
||||
validation {
|
||||
error_message = "Restart policy must be either 'any', 'on-failure', or 'none'."
|
||||
condition = var.restart_policy == "any" || var.restart_policy == "on-failure" || var.restart_policy == "none"
|
||||
}
|
||||
}
|
||||
variable "one_shot" {
|
||||
type = bool
|
||||
default = false
|
||||
|
@ -38,19 +47,20 @@ variable "volumes" {
|
|||
default = {}
|
||||
description = "A map of volume names to create and mount. The key is the volume name, and the value is the mount point."
|
||||
}
|
||||
variable "remote_volumes" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "A map of remote volumes to mount into the container."
|
||||
}
|
||||
variable "mounts" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "A map of host paths to container paths to mount. The key is the host path, and the value is the container path."
|
||||
}
|
||||
variable "configs" {
|
||||
type = map(object({
|
||||
name_prefix = list(string),
|
||||
contents = string,
|
||||
path = string
|
||||
}))
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "A map of config names to create and mount. The key is the config name, and the value is the config contents."
|
||||
description = "A map of config files to create. Key being the path to the file, and the value being the content. The config will be created using the truncated file name and a timestamp."
|
||||
}
|
||||
variable "ports" {
|
||||
type = list(object({
|
||||
|
@ -120,6 +130,11 @@ variable "operating_system" {
|
|||
type = string
|
||||
description = "The operating system to use for the service. Almost always 'linux'."
|
||||
}
|
||||
variable "converge_enable" {
|
||||
default = true
|
||||
type = bool
|
||||
description = "Whether to enable the converge configuration."
|
||||
}
|
||||
variable "converge_timeout" {
|
||||
default = "2m"
|
||||
type = string
|
||||
|
|
19
docker/service/locals.tf
Normal file
19
docker/service/locals.tf
Normal file
|
@ -0,0 +1,19 @@
|
|||
locals {
|
||||
// Name can be 64 bytes long, including a null byte seemingly, limiting the length to 63.
|
||||
service_name = join("-", [
|
||||
substr(var.stack_name, 0, 20),
|
||||
substr(var.service_name, 0, 63 - 1 - 20),
|
||||
])
|
||||
|
||||
# Define service labels en-masse
|
||||
labels = merge(var.labels, {
|
||||
"com.docker.stack.namespace" = var.stack_name
|
||||
"com.docker.stack.image" = data.docker_registry_image.image.name
|
||||
"com.docker.stack.hash" = data.docker_registry_image.image.sha256_digest
|
||||
"ooo.grey.service.stack" = var.stack_name
|
||||
"ooo.grey.service.name" = var.service_name
|
||||
#"ooo.grey.service.created" = timestamp()
|
||||
"ooo.grey.service.image" = data.docker_registry_image.image.name
|
||||
"ooo.grey.service.hash" = data.docker_registry_image.image.sha256_digest
|
||||
})
|
||||
}
|
|
@ -1,21 +1,10 @@
|
|||
resource "docker_volume" "volume" {
|
||||
for_each = var.volumes
|
||||
name = lower("${var.stack_name}-${replace(each.key, "/", "-")}")
|
||||
}
|
||||
|
||||
variable "remote_volumes" {
|
||||
type = map(string)
|
||||
description = "A map of remote volumes to mount into the container."
|
||||
default = {}
|
||||
}
|
||||
|
||||
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}"
|
||||
name = local.service_name
|
||||
|
||||
# Define the task spec
|
||||
task_spec {
|
||||
|
@ -33,14 +22,18 @@ resource "docker_service" "instance" {
|
|||
type = "volume"
|
||||
}
|
||||
}
|
||||
|
||||
# Mount all the volumes being remotely attached to the container
|
||||
dynamic "mounts" {
|
||||
for_each = var.remote_volumes
|
||||
content {
|
||||
target = mounts.value
|
||||
source = mounts.key
|
||||
type = "bind"
|
||||
type = "volume"
|
||||
}
|
||||
}
|
||||
|
||||
# Iterate through "mounts" to bind host paths to container paths
|
||||
dynamic "mounts" {
|
||||
for_each = var.mounts
|
||||
content {
|
||||
|
@ -50,12 +43,13 @@ resource "docker_service" "instance" {
|
|||
}
|
||||
}
|
||||
|
||||
# Iterate through configs and attach the docker configs
|
||||
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
|
||||
config_id = module.config[configs.key].id
|
||||
config_name = module.config[configs.key].name
|
||||
file_name = configs.value
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,26 +61,18 @@ resource "docker_service" "instance" {
|
|||
}
|
||||
}
|
||||
|
||||
# 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 healthcheck settings
|
||||
healthcheck {
|
||||
test = var.healthcheck != null ? var.healthcheck : []
|
||||
interval = var.healthcheck != null ? "10s" : "0s"
|
||||
timeout = var.healthcheck != null ? "3s" : "0s"
|
||||
retries = 0
|
||||
start_period = "0s"
|
||||
}
|
||||
|
||||
# Apply the list of Container Labels
|
||||
dynamic "labels" {
|
||||
for_each = var.labels
|
||||
for_each = local.labels
|
||||
content {
|
||||
label = labels.key
|
||||
value = labels.value
|
||||
|
@ -104,7 +90,7 @@ resource "docker_service" "instance" {
|
|||
|
||||
# Apply restart policy
|
||||
restart_policy {
|
||||
condition = var.one_shot ? "none" : "any"
|
||||
condition = var.one_shot ? "none" : var.restart_policy
|
||||
delay = "0s"
|
||||
window = "0s"
|
||||
max_attempts = 0
|
||||
|
@ -136,9 +122,14 @@ resource "docker_service" "instance" {
|
|||
}
|
||||
}
|
||||
|
||||
# Behaviour regarding startup and delaying/waiting. Not possible in global deploy mode.
|
||||
# Behaviour regarding startup and delaying/waiting.
|
||||
# Converging is not possible when:
|
||||
# * in global deploy mode
|
||||
# * in one-shot mode
|
||||
# * converging is disabled
|
||||
# * the service does not have a well-defined healthcheck, maybe you should add one to the service, or to the container itself ideally.
|
||||
dynamic "converge_config" {
|
||||
for_each = !var.global && !var.one_shot ? [{}] : []
|
||||
for_each = var.converge_enable && !var.global && !var.one_shot ? [{}] : []
|
||||
content {
|
||||
delay = "5s"
|
||||
timeout = var.converge_timeout
|
||||
|
@ -172,27 +163,11 @@ resource "docker_service" "instance" {
|
|||
}
|
||||
|
||||
# Service Labels
|
||||
labels {
|
||||
label = "com.docker.stack.namespace"
|
||||
value = var.stack_name
|
||||
}
|
||||
labels {
|
||||
label = "com.docker.stack.image"
|
||||
value = var.image
|
||||
dynamic "labels" {
|
||||
for_each = local.labels
|
||||
content {
|
||||
label = labels.key
|
||||
value = labels.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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}"
|
||||
}
|
8
docker/service/volume.tf
Normal file
8
docker/service/volume.tf
Normal file
|
@ -0,0 +1,8 @@
|
|||
resource "docker_volume" "volume" {
|
||||
for_each = var.volumes
|
||||
name = lower(join("-", [
|
||||
substr(var.stack_name, 0, 20),
|
||||
substr(var.service_name, 0, 20),
|
||||
substr(replace(trim(each.key, "/"), "/", "-"), 0, 20)
|
||||
]))
|
||||
}
|
13
docker/volume/inputs.tf
Normal file
13
docker/volume/inputs.tf
Normal file
|
@ -0,0 +1,13 @@
|
|||
variable "stack_name" {
|
||||
description = "The name of the collective stack"
|
||||
type = string
|
||||
}
|
||||
variable "volume_name" {
|
||||
description = "The name of the volume"
|
||||
type = string
|
||||
}
|
||||
variable "labels" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "A map of labels to apply to the service"
|
||||
}
|
15
docker/volume/locals.tf
Normal file
15
docker/volume/locals.tf
Normal file
|
@ -0,0 +1,15 @@
|
|||
locals {
|
||||
volume_name = substr(join("-", [
|
||||
substr(var.stack_name, 0, 20),
|
||||
substr(var.volume_name, 0, 64 - 1 - 3 - 20 - 6 - 6),
|
||||
formatdate("YYMMDD", timestamp()),
|
||||
formatdate("hhmmss", timestamp()),
|
||||
]), 0, 63)
|
||||
|
||||
labels = merge(var.labels, {
|
||||
"com.docker.stack.namespace" = var.stack_name
|
||||
"ooo.grey.volume.stack" = var.stack_name
|
||||
"ooo.grey.volume.name" = var.volume_name
|
||||
#"ooo.grey.volume.created" = timestamp()
|
||||
})
|
||||
}
|
3
docker/volume/output.tf
Normal file
3
docker/volume/output.tf
Normal file
|
@ -0,0 +1,3 @@
|
|||
output "source" {
|
||||
value = docker_volume.volume.id
|
||||
}
|
11
docker/volume/terraform.tf
Normal file
11
docker/volume/terraform.tf
Normal file
|
@ -0,0 +1,11 @@
|
|||
terraform {
|
||||
required_version = "~> 1.6"
|
||||
required_providers {
|
||||
docker = {
|
||||
source = "kreuzwerker/docker"
|
||||
version = "~>3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
17
docker/volume/volume.tf
Normal file
17
docker/volume/volume.tf
Normal file
|
@ -0,0 +1,17 @@
|
|||
resource "docker_volume" "volume" {
|
||||
name = local.volume_name
|
||||
|
||||
# Attach labels
|
||||
dynamic "labels" {
|
||||
for_each = local.labels
|
||||
content {
|
||||
label = labels.key
|
||||
value = labels.value
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
create_before_destroy = true
|
||||
ignore_changes = [name]
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ module "forgejo_actions_runner" {
|
|||
placement_constraints = var.placement_constraints
|
||||
image = "${var.forgejo_actions_runner_image}:${var.forgejo_actions_runner_version}"
|
||||
parallelism = var.parallelism
|
||||
converge_enable = false
|
||||
environment_variables = {
|
||||
forgejo_INSTANCE_URL = var.forgejo_instance_url
|
||||
forgejo_RUNNER_NAME = var.forgejo_runner_name
|
||||
|
@ -16,7 +17,7 @@ module "forgejo_actions_runner" {
|
|||
"/var/run/docker.sock" = "/var/run/docker.sock"
|
||||
}
|
||||
configs = {
|
||||
forgejo-config = {
|
||||
forgejo-config = yamlencode({
|
||||
name_prefix = ["forgejo-config", var.stack_name, var.service_name]
|
||||
path = "/config.yaml"
|
||||
contents = yamlencode({
|
||||
|
@ -54,6 +55,6 @@ module "forgejo_actions_runner" {
|
|||
workdir_parent : null
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue