From 7e3c6179a580d158f13a8a92b8ebae17317a7959 Mon Sep 17 00:00:00 2001 From: James Petersen Date: Thu, 2 May 2024 13:20:32 -0600 Subject: [PATCH 1/6] update keda terraform to latest patterns Signed-off-by: James Petersen --- images/keda/config/main.tf | 35 ++++++ images/keda/configs/latest.adapter.apko.yaml | 18 --- .../keda/configs/latest.controller.apko.yaml | 18 --- images/keda/configs/latest.webhooks.apko.yaml | 18 --- images/keda/main.tf | 46 ++++---- images/keda/tests/main.tf | 111 ++++++++++-------- images/keda/tests/smoke-test.sh | 6 - 7 files changed, 125 insertions(+), 127 deletions(-) create mode 100644 images/keda/config/main.tf delete mode 100644 images/keda/configs/latest.adapter.apko.yaml delete mode 100644 images/keda/configs/latest.controller.apko.yaml delete mode 100644 images/keda/configs/latest.webhooks.apko.yaml diff --git a/images/keda/config/main.tf b/images/keda/config/main.tf new file mode 100644 index 0000000000..7363ed2a4f --- /dev/null +++ b/images/keda/config/main.tf @@ -0,0 +1,35 @@ +variable "name" { + description = "Package name (e.g. keda, keda-adapter, keda-admission-webhooks)" +} + +variable "extra_packages" { + description = "Additional packages to install." + type = list(string) + default = [] +} + +locals { + entrypoints = { + "keda" = "/usr/bin/keda --zap-log-level=info --zap-encoder=console", + "keda-adapter" = "/usr/bin/keda-adapter --secure-port=6443 --logtostderr=true --v=0", + "keda-admission-webhooks" = "/usr/bin/keda-admission-webhooks --zap-log-level=info --zap-encoder=console", + } +} + +module "accts" { source = "../../../tflib/accts" } + +output "config" { + value = jsonencode({ + contents = { + packages = concat([ + var.name, // keda, keda-adapter, keda-admission-webhooks + "busybox", + "keda-compat", + ], var.extra_packages) + } + accounts = module.accts.block + entrypoint = { + command = local.entrypoints[var.name] + } + }) +} diff --git a/images/keda/configs/latest.adapter.apko.yaml b/images/keda/configs/latest.adapter.apko.yaml deleted file mode 100644 index 0a63c9a3a0..0000000000 --- a/images/keda/configs/latest.adapter.apko.yaml +++ /dev/null @@ -1,18 +0,0 @@ -contents: - packages: - - busybox - - keda-adapter - - keda-compat - -accounts: - groups: - - groupname: nonroot - gid: 65532 - users: - - username: nonroot - uid: 65532 - gid: 65532 - run-as: 65532 - -entrypoint: - command: /usr/bin/keda-adapter --secure-port=6443 --logtostderr=true --v=0 diff --git a/images/keda/configs/latest.controller.apko.yaml b/images/keda/configs/latest.controller.apko.yaml deleted file mode 100644 index 72d2eb301a..0000000000 --- a/images/keda/configs/latest.controller.apko.yaml +++ /dev/null @@ -1,18 +0,0 @@ -contents: - packages: - - busybox - - keda - - keda-compat - -accounts: - groups: - - groupname: nonroot - gid: 65532 - users: - - username: nonroot - uid: 65532 - gid: 65532 - run-as: 65532 - -entrypoint: - command: /usr/bin/keda --zap-log-level=info --zap-encoder=console diff --git a/images/keda/configs/latest.webhooks.apko.yaml b/images/keda/configs/latest.webhooks.apko.yaml deleted file mode 100644 index 249392c4ab..0000000000 --- a/images/keda/configs/latest.webhooks.apko.yaml +++ /dev/null @@ -1,18 +0,0 @@ -contents: - packages: - - busybox - - keda-admission-webhooks - - keda-compat - -accounts: - groups: - - groupname: nonroot - gid: 65532 - users: - - username: nonroot - uid: 65532 - gid: 65532 - run-as: 65532 - -entrypoint: - command: /usr/bin/keda-admission-webhooks --zap-log-level=info --zap-encoder=console diff --git a/images/keda/main.tf b/images/keda/main.tf index 0e7ff2e2d6..ff064849e9 100644 --- a/images/keda/main.tf +++ b/images/keda/main.tf @@ -1,25 +1,16 @@ locals { components = toset([ - "controller", - "adapter", - "webhooks", + "keda", + "keda-adapter", + "keda-admission-webhooks", ]) - packages = merge( - { for k in local.components : k => k }, - { - "controller" = "keda" - "adapter" = "keda-adapter" - "webhooks" = "keda-admission-webhooks" - }, - ) - repositories = merge( { for k in local.components : k => k }, { - "controller" = var.target_repository - "adapter" = "${var.target_repository}-adapter" - "webhooks" = "${var.target_repository}-admission-webhooks" + "keda" = var.target_repository + "keda-adapter" = "${var.target_repository}-adapter" + "keda-admission-webhooks" = "${var.target_repository}-admission-webhooks" }, ) } @@ -28,13 +19,28 @@ variable "target_repository" { description = "The docker repo into which the image and attestations should be published." } +module "config" { + for_each = local.components + source = "./config" + name = each.value +} + +module "versions" { + for_each = local.components + source = "../../tflib/versions" + package = each.value +} + module "latest" { - for_each = local.repositories + for_each = local.components source = "../../tflib/publisher" name = basename(path.module) - target_repository = each.value - config = file("${path.module}/configs/latest.${each.key}.apko.yaml") + target_repository = local.repositories[each.value] + config = module.config[each.value].config build-dev = true + + main_package = module.versions[each.value].versions[each.value].main + update-repo = module.versions[each.value].versions[each.value].is_latest } module "test-latest" { @@ -49,7 +55,7 @@ module "tagger" { depends_on = [module.test-latest] tags = { - "latest" = module.latest[each.key].image_ref - "latest-dev" = module.latest[each.key].dev_ref + "latest" = module.latest[each.value].image_ref + "latest-dev" = module.latest[each.value].dev_ref } } diff --git a/images/keda/tests/main.tf b/images/keda/tests/main.tf index 95f7d0c72d..08fd1b3697 100644 --- a/images/keda/tests/main.tf +++ b/images/keda/tests/main.tf @@ -1,27 +1,21 @@ terraform { required_providers { - oci = { source = "chainguard-dev/oci" } - helm = { source = "hashicorp/helm" } + oci = { source = "chainguard-dev/oci" } + imagetest = { source = "chainguard-dev/imagetest" } } } variable "digests" { description = "The image digests to run tests over." type = object({ - controller = string - adapter = string - webhooks = string + keda = string + keda-adapter = string + keda-admission-webhooks = string }) } -variable "skip_crds" { - description = "Used to deconflict between multiple installations within the same cluster." - default = false -} - -variable "chart-version" { - description = "The version of the Helm chart to install." - default = "latest" +variable "name" { + default = "keda" } data "oci_string" "ref" { @@ -29,45 +23,68 @@ data "oci_string" "ref" { input = each.value } -resource "helm_release" "keda" { - name = "keda" - namespace = "keda" - repository = "https://kedacore.github.io/charts" - chart = "keda" - create_namespace = true - timeout = 600 - - version = var.chart-version == "latest" ? null : var.chart-version +data "imagetest_inventory" "this" {} - values = [ - < Date: Fri, 3 May 2024 08:50:32 -0600 Subject: [PATCH 2/6] use tfgen with keda Signed-off-by: James Petersen --- Makefile | 2 +- generated.tf | 9 +++++++++ images/keda/generated.tf | 13 +++++++++++++ images/keda/main.tf | 14 +++++--------- main.tf | 5 ----- 5 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 images/keda/generated.tf diff --git a/Makefile b/Makefile index 480966ba59..4aeb6dfea0 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ TERRAFORM ?= $(shell command -v terraform) # These images either do something with Alpine, # or are somehow incompatible with tfgen (still using tagger etc.) -TFGEN_SKIP ?= busybox,calico,git,graalvm-native,harbor,k3s,keda,kubeflow,kubeflow-katib,maven,powershell,prometheus,static,terraform +TFGEN_SKIP ?= busybox,calico,git,graalvm-native,harbor,k3s,kubeflow,kubeflow-katib,maven,powershell,prometheus,static,terraform # These are the tfgen generators applied to this repo (in order) TFGEN_GENERATORS ?= Image01Outputs,Toplevel01Modules,Toplevel02Outputs diff --git a/generated.tf b/generated.tf index 9a70a33e8d..a15103a6b9 100644 --- a/generated.tf +++ b/generated.tf @@ -595,6 +595,11 @@ module "karpenter" { target_repository = "${var.target_repository}/karpenter" } +module "keda" { + source = "./images/keda" + target_repository = "${var.target_repository}/keda" +} + module "keycloak" { source = "./images/keycloak" target_repository = "${var.target_repository}/keycloak" @@ -1979,6 +1984,10 @@ output "summary_karpenter" { value = module.karpenter.summary } +output "summary_keda" { + value = module.keda.summary +} + output "summary_keycloak" { value = module.keycloak.summary } diff --git a/images/keda/generated.tf b/images/keda/generated.tf new file mode 100644 index 0000000000..e823b529aa --- /dev/null +++ b/images/keda/generated.tf @@ -0,0 +1,13 @@ +# DO NOT EDIT - this file is autogenerated by tfgen + +output "summary" { + value = merge( + { + for k, v in module.latest : k => { + "ref" = v.image_ref + "config" = v.config + "tags" = v.tag_list + } + }) +} + diff --git a/images/keda/main.tf b/images/keda/main.tf index ff064849e9..6fb3702097 100644 --- a/images/keda/main.tf +++ b/images/keda/main.tf @@ -26,9 +26,8 @@ module "config" { } module "versions" { - for_each = local.components - source = "../../tflib/versions" - package = each.value + source = "../../tflib/versions" + package = "keda" } module "latest" { @@ -39,8 +38,8 @@ module "latest" { config = module.config[each.value].config build-dev = true - main_package = module.versions[each.value].versions[each.value].main - update-repo = module.versions[each.value].versions[each.value].is_latest + main_package = "" + update-repo = true } module "test-latest" { @@ -54,8 +53,5 @@ module "tagger" { depends_on = [module.test-latest] - tags = { - "latest" = module.latest[each.value].image_ref - "latest-dev" = module.latest[each.value].dev_ref - } + tags = module.latest[each.key].latest_tag_map } diff --git a/main.tf b/main.tf index 53ef1be93b..314c183195 100644 --- a/main.tf +++ b/main.tf @@ -110,11 +110,6 @@ module "k3s" { target_repository = "${var.target_repository}/k3s" } -module "keda" { - source = "./images/keda" - target_repository = "${var.target_repository}/keda" -} - module "kubeflow" { source = "./images/kubeflow" target_repository = "${var.target_repository}/kubeflow" From f0a52a7bca36f933eef0eeaaa00150af0eb7d2c9 Mon Sep 17 00:00:00 2001 From: James Petersen Date: Fri, 3 May 2024 13:16:54 -0600 Subject: [PATCH 3/6] cross product Signed-off-by: James Petersen --- images/keda/generated.tf | 2 +- images/keda/main.tf | 48 ++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/images/keda/generated.tf b/images/keda/generated.tf index e823b529aa..e7a317ed5d 100644 --- a/images/keda/generated.tf +++ b/images/keda/generated.tf @@ -3,7 +3,7 @@ output "summary" { value = merge( { - for k, v in module.latest : k => { + for k, v in module.versioned : k => { "ref" = v.image_ref "config" = v.config "tags" = v.tag_list diff --git a/images/keda/main.tf b/images/keda/main.tf index 6fb3702097..6435c592e9 100644 --- a/images/keda/main.tf +++ b/images/keda/main.tf @@ -1,18 +1,24 @@ locals { + // List of all components components = toset([ "keda", "keda-adapter", "keda-admission-webhooks", ]) - repositories = merge( - { for k in local.components : k => k }, - { - "keda" = var.target_repository - "keda-adapter" = "${var.target_repository}-adapter" - "keda-admission-webhooks" = "${var.target_repository}-admission-webhooks" - }, - ) + // Cross product of versions and components + component_versions = merge([ + for component in local.components : merge([ + for key, version_metadata in module.versions.versions : { + join("-", compact([key, substr(component, 5, 100)])) : { + + is_latest = version_metadata.is_latest + component = component + main = join("-", compact([key, substr(component, 5, 100)])) + } + } + ]...) + ]...) } variable "target_repository" { @@ -20,9 +26,9 @@ variable "target_repository" { } module "config" { - for_each = local.components + for_each = local.component_versions source = "./config" - name = each.value + name = each.value.component } module "versions" { @@ -30,28 +36,28 @@ module "versions" { package = "keda" } -module "latest" { - for_each = local.components +module "versioned" { + for_each = local.component_versions source = "../../tflib/publisher" name = basename(path.module) - target_repository = local.repositories[each.value] - config = module.config[each.value].config + target_repository = "${var.target_repository}/${each.value.component}" + config = module.config[each.key].config build-dev = true - main_package = "" - update-repo = true + main_package = each.value.main + update-repo = each.value.is_latest } -module "test-latest" { +module "test" { source = "./tests" - digests = { for k, v in module.latest : k => v.image_ref } + digests = { for k, v in module.versioned : k => v.image_ref } } module "tagger" { - for_each = local.components + for_each = local.component_versions source = "../../tflib/tagger" - depends_on = [module.test-latest] + depends_on = [module.test] - tags = module.latest[each.key].latest_tag_map + tags = module.versioned[each.key].latest_tag_map } From e0fc405282a9cbccf39ae278a647a30c28f6ff01 Mon Sep 17 00:00:00 2001 From: James Petersen Date: Fri, 3 May 2024 15:51:21 -0600 Subject: [PATCH 4/6] add some comments on locals Signed-off-by: James Petersen --- images/keda/config/main.tf | 8 +++- images/keda/main.tf | 90 ++++++++++++++++++++++++++++++++------ 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/images/keda/config/main.tf b/images/keda/config/main.tf index 7363ed2a4f..81841e45e7 100644 --- a/images/keda/config/main.tf +++ b/images/keda/config/main.tf @@ -1,5 +1,9 @@ variable "name" { - description = "Package name (e.g. keda, keda-adapter, keda-admission-webhooks)" + description = "Component name (e.g. keda, keda-adapter, keda-admission-webhooks)" +} + +variable "package" { + description = "Package name (e.g. keda-2.14)" } variable "extra_packages" { @@ -22,7 +26,7 @@ output "config" { value = jsonencode({ contents = { packages = concat([ - var.name, // keda, keda-adapter, keda-admission-webhooks + var.package, // keda, keda-adapter, keda-admission-webhooks "busybox", "keda-compat", ], var.extra_packages) diff --git a/images/keda/main.tf b/images/keda/main.tf index 6435c592e9..2fa4e607ac 100644 --- a/images/keda/main.tf +++ b/images/keda/main.tf @@ -1,20 +1,71 @@ locals { - // List of all components + # List of all components components = toset([ "keda", "keda-adapter", "keda-admission-webhooks", ]) - // Cross product of versions and components + # List of versions. + # + # When version metadata is not available this will look like + # "versions" = [""] + # + # When version metadata is available this will look like + # "versions" = ["2.13", "2.14"] + # + # Order matters here, we want the latest version to be the last element in + # the list so it's tagged with latest. + versions = [ + for _, version_metadata in module.versions.versions : lookup(version_metadata, "version", "") + ] + + # Cross product of versions and components + # + # When version metadata is not available this will look like + # "component_versions" = { + # "keda" = { + # "component" = "keda" + # "is_latest" = true + # "main" = "keda" + # } + # "keda-adapter" = { + # "component" = "keda-adapter" + # "is_latest" = true + # "main" = "keda-adapter" + # } + # ... + # } + # + # When version metadata is not available this will look like + # "component_versions" = { + # "keda2.14" = { + # "component" = "keda" + # "is_latest" = true + # "main" = "keda-2.14" + # } + # "keda-adapter2.14" = { + # "component" = "keda-adapter" + # "is_latest" = true + # "main" = "keda-2.14-adapter" + # } + # ... + # } component_versions = merge([ for component in local.components : merge([ for key, version_metadata in module.versions.versions : { - join("-", compact([key, substr(component, 5, 100)])) : { + # This sets the key to `$component` when version data does not exist and + # `$component$version` when version data exists. We just smash the two + # together to make it easier to access in subsequent modules. + format("%s%s", component, lookup(version_metadata, "version", "")) : { is_latest = version_metadata.is_latest component = component - main = join("-", compact([key, substr(component, 5, 100)])) + + # Strips off `keda` or `keda-` from the components and joins with the + # version_metadata key which will be `keda` when version data does not + # exist and `keda-$version` when version data exists + main = join("-", compact([key, substr(component, 5, 100)])) } } ]...) @@ -25,17 +76,21 @@ variable "target_repository" { description = "The docker repo into which the image and attestations should be published." } +# Versions module plugs into to the version metadata for the top-level package +module "versions" { + source = "../../tflib/versions" + package = basename(path.module) +} + +# Need a config for every version of every component module "config" { for_each = local.component_versions source = "./config" name = each.value.component + package = each.value.main } -module "versions" { - source = "../../tflib/versions" - package = "keda" -} - +# Need a publisher invocation for every version of every component module "versioned" { for_each = local.component_versions source = "../../tflib/publisher" @@ -48,16 +103,25 @@ module "versioned" { update-repo = each.value.is_latest } +# Tests need to be grouped by version. We want to test all components of +# the same version at the same time. module "test" { - source = "./tests" - digests = { for k, v in module.versioned : k => v.image_ref } + for_each = toset(local.versions) + source = "./tests" + + digests = { for component in local.components : component => module.versioned["${component}${each.value}"].image_ref } + name = "${basename(path.module)}${each.value}" } +# Tagger should be grouped by components. We want to tag multiple versions of +# the same component so we iterate over the versions list for each component module "tagger" { - for_each = local.component_versions + for_each = local.components source = "../../tflib/tagger" depends_on = [module.test] - tags = module.versioned[each.key].latest_tag_map + tags = merge( + [for version in local.versions : module.versioned["${each.value}${version}"].latest_tag_map]... + ) } From 3c7cb06216339a9088526b98ad419b50ea148ec8 Mon Sep 17 00:00:00 2001 From: James Petersen Date: Mon, 6 May 2024 14:52:23 -0600 Subject: [PATCH 5/6] properly set target repo Signed-off-by: James Petersen --- images/keda/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/keda/main.tf b/images/keda/main.tf index 2fa4e607ac..90795024c6 100644 --- a/images/keda/main.tf +++ b/images/keda/main.tf @@ -95,7 +95,7 @@ module "versioned" { for_each = local.component_versions source = "../../tflib/publisher" name = basename(path.module) - target_repository = "${var.target_repository}/${each.value.component}" + target_repository = replace(var.target_repository, "/keda", "/${each.value.component}") config = module.config[each.key].config build-dev = true From 38e075c535c5db40950f2dd4a2dd501b140c0a9a Mon Sep 17 00:00:00 2001 From: James Petersen Date: Mon, 6 May 2024 14:56:35 -0600 Subject: [PATCH 6/6] remove hard coded bounds Signed-off-by: James Petersen --- images/keda/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/keda/main.tf b/images/keda/main.tf index 90795024c6..282d2aeb4b 100644 --- a/images/keda/main.tf +++ b/images/keda/main.tf @@ -65,7 +65,7 @@ locals { # Strips off `keda` or `keda-` from the components and joins with the # version_metadata key which will be `keda` when version data does not # exist and `keda-$version` when version data exists - main = join("-", compact([key, substr(component, 5, 100)])) + main = join("-", compact([key, trimprefix(replace(component, "keda", ""), "-")])) } } ]...)