Fix builder, add support for passing debug_path into configs so that they can be grouped into services

This commit is contained in:
Greyscale 2024-12-26 15:40:11 +01:00
parent 51a89a72ac
commit 5224b46ccf
Signed by: grey
GPG key ID: DDB392AE64B32D89
7 changed files with 59 additions and 35 deletions

View file

@ -1,6 +1,14 @@
resource "local_file" "config" { resource "local_file" "config" {
count = var.debug ? 1 : 0 count = var.debug ? 1 : 0
content = var.value content = var.value
filename = "${path.root}/.debug/docker/${var.stack_name}/configs/${local.file_name}" filename = "${local.debug_path}/${local.file_name}"
file_permission = "0600" file_permission = "0600"
}
variable "debug_path" {
type = string
description = "Path to write debug files to"
default = null
}
locals {
debug_path = var.debug_path != null ? var.debug_path : "${path.root}/.debug/docker/configs/${var.stack_name}"
} }

View file

@ -4,4 +4,5 @@ module "config" {
stack_name = var.stack_name stack_name = var.stack_name
name = each.key name = each.key
value = each.value value = each.value
debug_path = "${local.debug_path}/configs"
} }

View file

@ -1,10 +1,19 @@
variable "debug_path" {
type = string
description = "Path to write debug files to"
default = null
}
locals {
debug_path = var.debug_path != null ? var.debug_path : "${path.root}/.debug/docker/services/${var.stack_name}/${var.service_name}"
}
resource "local_file" "debug" { resource "local_file" "debug" {
filename = "${path.root}/.debug/docker/${var.service_name}/service.json" filename = "${local.debug_path}/service.json"
file_permission = "0600" file_permission = "0600"
content = nonsensitive(jsonencode({ content = nonsensitive(jsonencode({
name = local.service_name name = local.service_name
stack = var.stack_name stack = var.stack_name
#image = local.image image = local.image_fully_qualified
build = var.build build = var.build
networks = var.networks networks = var.networks
ports = var.ports ports = var.ports

View file

@ -1,6 +1,5 @@
locals { locals {
is_build = var.build != null is_build = var.build != null
// strip off the tag
image_name = split(":", var.image)[0] image_name = split(":", var.image)[0]
source_files = local.is_build ? fileset(var.build.context, "**") : [] source_files = local.is_build ? fileset(var.build.context, "**") : []
@ -14,7 +13,7 @@ locals {
] ]
} }
resource "random_pet" "build" { resource "random_pet" "build" {
count = local.is_build ? 1 : 0 for_each = local.is_build ? { "build" = {} } : {}
keepers = { keepers = {
image_name = local.image_name image_name = local.image_name
build_context = var.build.context build_context = var.build.context
@ -22,26 +21,31 @@ resource "random_pet" "build" {
target = var.build.target target = var.build.target
tags = jsonencode(local.tags) tags = jsonencode(local.tags)
hash = local.image_context_hash hash = local.image_context_hash
args = jsonencode(var.build.args)
dockerfile = var.build.dockerfile
} }
} }
# MB: This is a hack to allow replace_triggered_by on a resource that may or may not exist.
resource "terraform_data" "conditional_build" {
input = try(jsonencode(random_pet.build["build"].keepers), null)
}
// Do the build // Do the build
resource "docker_image" "build" { resource "docker_image" "build" {
count = local.is_build ? 1 : 0 for_each = local.is_build ? { "build" = {} } : {}
name = var.image name = var.image
force_remove = false force_remove = false
build { build {
# We are reading these variables via the random_pet entity to ensure that the build is triggered when changes happen # We are reading these variables via the random_pet entity to ensure that the build is triggered when changes happen
context = random_pet.build[0].keepers.build_context context = random_pet.build["build"].keepers.build_context
tag = jsondecode(random_pet.build[0].keepers.tags) tag = jsondecode(random_pet.build["build"].keepers.tags)
target = random_pet.build[0].keepers.target target = random_pet.build["build"].keepers.target
remove = false build_args = jsondecode(random_pet.build["build"].keepers.args)
dockerfile = random_pet.build["build"].keepers.dockerfile
remove = false
suppress_output = false
} }
lifecycle { lifecycle {
ignore_changes = [ replace_triggered_by = [terraform_data.conditional_build, ]
build,
]
replace_triggered_by = [random_pet.build, ]
create_before_destroy = true create_before_destroy = true
} }
} }
@ -49,11 +53,11 @@ resource "docker_image" "build" {
// Push it to the registry // Push it to the registry
resource "docker_registry_image" "build" { resource "docker_registry_image" "build" {
depends_on = [docker_image.build] depends_on = [docker_image.build]
count = local.is_build ? 1 : 0 for_each = local.is_build ? { "build" = {} } : {}
name = docker_image.build[0].name name = docker_image.build["build"].name
keep_remotely = true keep_remotely = true
lifecycle { lifecycle {
replace_triggered_by = [random_pet.build] replace_triggered_by = [terraform_data.conditional_build]
} }
} }
resource "docker_registry_image" "tags" { resource "docker_registry_image" "tags" {
@ -62,7 +66,7 @@ resource "docker_registry_image" "tags" {
name = each.value name = each.value
keep_remotely = true keep_remotely = true
lifecycle { lifecycle {
replace_triggered_by = [random_pet.build] replace_triggered_by = [terraform_data.conditional_build]
ignore_changes = [ ignore_changes = [
name, name,
] ]

View file

@ -2,18 +2,18 @@ locals {
is_mirror = var.mirror != null is_mirror = var.mirror != null
} }
resource "docker_image" "source" { resource "docker_image" "source" {
count = local.is_mirror ? 1 : 0 for_each = local.is_mirror ? { "mirror" = {} } : {}
name = data.docker_registry_image.image[0].name name = data.docker_registry_image.image[0].name
pull_triggers = [data.docker_registry_image.image[0].sha256_digest] pull_triggers = [data.docker_registry_image.image[0].sha256_digest]
force_remove = false force_remove = false
} }
resource "docker_tag" "retagged" { resource "docker_tag" "retagged" {
count = local.is_mirror ? 1 : 0 for_each = local.is_mirror ? { "mirror" = {} } : {}
source_image = docker_image.source[0].name source_image = docker_image.source[0].name
target_image = var.mirror target_image = var.mirror
} }
resource "docker_registry_image" "mirror" { resource "docker_registry_image" "mirror" {
count = local.is_mirror ? 1 : 0 for_each = local.is_mirror ? { "mirror" = {} } : {}
depends_on = [docker_tag.retagged[0]] depends_on = [docker_tag.retagged[0]]
name = docker_tag.retagged[0].target_image name = docker_tag.retagged[0].target_image
keep_remotely = true keep_remotely = true

View file

@ -1,6 +1,6 @@
data "docker_registry_image" "image" { data "docker_registry_image" "image" {
count = local.is_build == false ? 1 : 0 for_each = !local.is_build ? { "default" = {} } : {}
name = var.image name = var.image
} }
locals { locals {
// Name can be 64 bytes long, including a null byte seemingly, limiting the length to 63. // Name can be 64 bytes long, including a null byte seemingly, limiting the length to 63.
@ -11,20 +11,20 @@ locals {
# Calculate the docker image to use # Calculate the docker image to use
image = ( image = (
local.is_build local.is_build
? docker_image.build[0].name ? docker_image.build["build"].name
: ( : (
local.is_mirror local.is_mirror
? docker_registry_image.mirror[0].name ? docker_registry_image.mirror["mirror"].name
: data.docker_registry_image.image[0].name : data.docker_registry_image.image["default"].name
) )
) )
image_fully_qualified = ( image_fully_qualified = (
local.is_build local.is_build
? docker_image.build[0].name ? "${docker_registry_image.build["build"].name}@${docker_registry_image.build["build"].sha256_digest}"
: ( : (
local.is_mirror local.is_mirror
? "${docker_registry_image.mirror[0].name}@${docker_registry_image.mirror[0].sha256_digest}" ? "${docker_registry_image.mirror["mirror"].name}@${docker_registry_image.mirror["mirror"].sha256_digest}"
: "${data.docker_registry_image.image[0].name}@${data.docker_registry_image.image[0].sha256_digest}" : "${data.docker_registry_image.image["default"].name}@${data.docker_registry_image.image["default"].sha256_digest}"
) )
) )
} }

View file

@ -2,6 +2,8 @@ resource "docker_service" "instance" {
# The name of the service is the stack name and the service name combined # The name of the service is the stack name and the service name combined
name = local.service_name name = local.service_name
#depends_on = [terraform_data.conditional_build_hack["build"]]
# Define the task spec # Define the task spec
task_spec { task_spec {
container_spec { container_spec {
@ -188,6 +190,6 @@ resource "docker_service" "instance" {
lifecycle { lifecycle {
# Help prevent "this service already exists" irritations # Help prevent "this service already exists" irritations
create_before_destroy = false create_before_destroy = false
replace_triggered_by = [docker_image.build[0].id] #replace_triggered_by = [terraform_data.conditional_build_hack["build"]]
} }
} }