From 506212b337fecc6fcc9cd059c9287af3ce8393dc Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 14:38:14 +0100 Subject: [PATCH 01/14] fix: support 'null' workaround as optional input in Panel --- modules/stackit/git-repository/buildingblock/main.tf | 8 +++++--- modules/stackit/git-repository/buildingblock/variables.tf | 4 ++-- modules/stackit/git-repository/meshstack_integration.tf | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/stackit/git-repository/buildingblock/main.tf b/modules/stackit/git-repository/buildingblock/main.tf index d4b02a13..b8c9ad12 100644 --- a/modules/stackit/git-repository/buildingblock/main.tf +++ b/modules/stackit/git-repository/buildingblock/main.tf @@ -1,4 +1,6 @@ -# ── Repository ───────────────────────────────────────────────────────────────── +locals { + have_clone_addr = trimspace(var.clone_addr) != "" && var.clone_addr != "null" +} resource "forgejo_repository" "repository" { owner = var.forgejo_organization @@ -6,9 +8,9 @@ resource "forgejo_repository" "repository" { description = var.description private = var.private default_branch = var.default_branch - auto_init = var.clone_addr == "" + auto_init = !local.have_clone_addr # One-time clone (not an ongoing mirror) - clone_addr = var.clone_addr != "" ? var.clone_addr : null + clone_addr = local.have_clone_addr ? var.clone_addr : null mirror = false } diff --git a/modules/stackit/git-repository/buildingblock/variables.tf b/modules/stackit/git-repository/buildingblock/variables.tf index d9a843a9..c6d467c8 100644 --- a/modules/stackit/git-repository/buildingblock/variables.tf +++ b/modules/stackit/git-repository/buildingblock/variables.tf @@ -51,6 +51,6 @@ variable "default_branch" { variable "clone_addr" { type = string - description = "Optional URL to clone into this repository, e.g. 'https://github.com/owner/repo.git'. Leave empty to create an empty repository." - default = "" + description = "Optional URL to clone into this repository, e.g. 'https://github.com/owner/repo.git'. Leave empty or `null` to create an empty repository." + default = "null" # supporting the null string is a workaround for the Panel UI which does not support empty string as default for optional value } diff --git a/modules/stackit/git-repository/meshstack_integration.tf b/modules/stackit/git-repository/meshstack_integration.tf index a071a198..f57d8906 100644 --- a/modules/stackit/git-repository/meshstack_integration.tf +++ b/modules/stackit/git-repository/meshstack_integration.tf @@ -135,10 +135,10 @@ resource "meshstack_building_block_definition" "this" { clone_addr = { display_name = "Clone from URL" - description = "Optional URL to clone into this repository, e.g. 'https://github.com/owner/repo.git'. Leave empty to create an empty repository." + description = "Optional URL to clone into this repository, e.g. 'https://github.com/owner/repo.git'. Leave `null` to create an empty repository." type = "STRING" assignment_type = "USER_INPUT" - default_value = jsonencode("") + default_value = jsonencode("null") } } From 84092aea34fa08cca445ee0b74c5846da6a4e581 Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 11:35:29 +0100 Subject: [PATCH 02/14] feat(git-repository): support action_secrets, refactor ske starterkit backplane to LCF --- modules/ske/ske-starterkit/backplane/main.tf | 42 ----------------- .../ske-starterkit/buildingblock/README.md | 6 +-- .../ske-starterkit/meshstack_integration.tf | 46 +++++++++---------- modules/stackit/git-repository/README.md | 1 + .../git-repository/buildingblock/README.md | 4 +- .../git-repository/buildingblock/main.tf | 8 ++++ .../git-repository/buildingblock/variables.tf | 12 +++++ .../git-repository/meshstack_integration.tf | 23 ++++++++++ 8 files changed, 71 insertions(+), 71 deletions(-) delete mode 100644 modules/ske/ske-starterkit/backplane/main.tf diff --git a/modules/ske/ske-starterkit/backplane/main.tf b/modules/ske/ske-starterkit/backplane/main.tf deleted file mode 100644 index 4221baac..00000000 --- a/modules/ske/ske-starterkit/backplane/main.tf +++ /dev/null @@ -1,42 +0,0 @@ -variable "meshstack" { - type = object({ - owning_workspace_identifier = string - }) -} - -variable "hub" { - type = object({ - git_ref = string - bbd_draft = bool - }) -} - -variable "forgejo_token" { - type = string - sensitive = true -} - -variable "forgejo_organization" { - type = string -} - -variable "forgejo_base_url" { - type = string -} - -output "building_block_definition_version_refs" { - value = { - "git-repository" : module.git_repository.building_block_definition_version_ref - } -} - -module "git_repository" { - source = "github.com/meshcloud/meshstack-hub//modules/stackit/git-repository?ref=2e990f277119f33db50af78032768c434ab4b7bb" - - meshstack = var.meshstack - hub = var.hub - - forgejo_token = var.forgejo_token - forgejo_organization = var.forgejo_organization - forgejo_base_url = var.forgejo_base_url -} diff --git a/modules/ske/ske-starterkit/buildingblock/README.md b/modules/ske/ske-starterkit/buildingblock/README.md index 351e0e13..1296cd20 100644 --- a/modules/ske/ske-starterkit/buildingblock/README.md +++ b/modules/ske/ske-starterkit/buildingblock/README.md @@ -34,11 +34,11 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [building\_block\_definition\_version\_refs](#input\_building\_block\_definition\_version\_refs) | n/a | `map(object({ uuid = string }))` | n/a | yes | -| [creator](#input\_creator) | Information about the creator of the resources who will be assigned Project Admin role |
object({
type = string
identifier = string
displayName = string
username = optional(string)
email = optional(string)
euid = optional(string)
})
| n/a | yes | +| [creator](#input\_creator) | Information about the creator of the resources who will be assigned Project Admin role |
object({
type = string
identifier = string
displayName = string
username = optional(string)
email = optional(string)
euid = optional(string)
})
| n/a | yes | | [full\_platform\_identifier](#input\_full\_platform\_identifier) | Full platform identifier of the SKE platform. | `string` | n/a | yes | -| [landing\_zone\_identifiers](#input\_landing\_zone\_identifiers) | SKE Landing zone identifiers for the dev/prod meshTenant. |
object({
dev = string
prod = string
})
| n/a | yes | +| [landing\_zone\_identifiers](#input\_landing\_zone\_identifiers) | SKE Landing zone identifiers for the dev/prod meshTenant. |
object({
dev = string
prod = string
})
| n/a | yes | | [name](#input\_name) | This name will be used for the created projects. | `string` | n/a | yes | -| [project\_tags](#input\_project\_tags) | Tags for dev/prod meshProject. |
object({
dev : map(list(string))
prod : map(list(string))

owner_tag_key = optional(string, null)
})
| n/a | yes | +| [project\_tags](#input\_project\_tags) | Tags for dev/prod meshProject. |
object({
dev : map(list(string))
prod : map(list(string))

owner_tag_key = optional(string, null)
})
| n/a | yes | | [repo\_clone\_addr](#input\_repo\_clone\_addr) | URL to clone into the starterkit git repository. | `string` | n/a | yes | | [workspace\_identifier](#input\_workspace\_identifier) | n/a | `string` | n/a | yes | diff --git a/modules/ske/ske-starterkit/meshstack_integration.tf b/modules/ske/ske-starterkit/meshstack_integration.tf index b2304344..095fb109 100644 --- a/modules/ske/ske-starterkit/meshstack_integration.tf +++ b/modules/ske/ske-starterkit/meshstack_integration.tf @@ -4,19 +4,6 @@ variable "meshstack" { }) } -variable "forgejo_token" { - type = string - sensitive = true -} - -variable "forgejo_organization" { - type = string -} - -variable "forgejo_base_url" { - type = string -} - variable "full_platform_identifier" { type = string } @@ -55,6 +42,13 @@ variable "notification_subscribers" { default = [] } +variable "building_block_definition_version_refs" { + type = map(object({ + content_hash = string # adding the content nicely tracks changes in dependent BBDs (draft mode) + uuid = string + })) +} + variable "hub" { type = object({ git_ref = optional(string, "main") @@ -67,17 +61,6 @@ variable "hub" { EOT } -module "backplane" { - source = "./backplane" # TODO revert to github.com/meshcloud/meshstack-hub//modules/ske/ske-starterkit/backplane link once pushed - - meshstack = var.meshstack - hub = var.hub - - forgejo_token = var.forgejo_token - forgejo_organization = var.forgejo_organization - forgejo_base_url = var.forgejo_base_url -} - locals { name_regex = "^[a-zA-Z0-9-]+$" # underscore and dots not allowed because of K8s namespace } @@ -204,7 +187,20 @@ EOT description = "Refs used to create auxiliary building blocks (composition)." display_name = "BBD Version Refs" # jsonencode twice is correct, see https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/building_block_definition#argument-1 - argument = jsonencode(jsonencode(module.backplane.building_block_definition_version_refs)) + argument = jsonencode(jsonencode(var.building_block_definition_version_refs)) + }, + # TODO remove before merge, leftover from dev attempts in grubinator2 instance + "git_repository_action_secrets" = { + assignment_type = "STATIC" + type = "CODE" + description = "REMOVEME Static sensitive Forgejo Actions secrets passed to the composed git-repository building block." + display_name = "REMOVEME Git Repository Action Secrets" + # jsonencode twice is correct, see https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/building_block_definition#argument-1 + sensitive = { + argument = { + secret_value = jsonencode({}) + } + } } } diff --git a/modules/stackit/git-repository/README.md b/modules/stackit/git-repository/README.md index a1fecd14..ec502005 100644 --- a/modules/stackit/git-repository/README.md +++ b/modules/stackit/git-repository/README.md @@ -14,6 +14,7 @@ It combines: - workspace-level target type - static inputs from backplane (`forgejo_base_url`, `forgejo_token`, `forgejo_organization`) +- optional static sensitive action secrets (`action_secrets`) - user inputs (`name`, `description`, `private`, `clone_addr`) - outputs exposed to users (`repository_html_url`, `repository_clone_url`, `repository_ssh_url`, `summary`) diff --git a/modules/stackit/git-repository/buildingblock/README.md b/modules/stackit/git-repository/buildingblock/README.md index 8ff4c960..92c494f7 100644 --- a/modules/stackit/git-repository/buildingblock/README.md +++ b/modules/stackit/git-repository/buildingblock/README.md @@ -22,12 +22,14 @@ No modules. | Name | Type | |------|------| | [forgejo_repository.repository](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository) | resource | +| [forgejo_repository_action_secret.action_secrets](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [clone\_addr](#input\_clone\_addr) | Optional URL to clone into this repository, e.g. 'https://github.com/owner/repo.git'. Leave empty to create an empty repository. | `string` | `""` | no | +| [action\_secrets](#input\_action\_secrets) | Map of Forgejo Actions secrets to create in the repository. | `map(string)` | `{}` | no | +| [clone\_addr](#input\_clone\_addr) | Optional URL to clone into this repository, e.g. 'https://github.com/owner/repo.git'. Leave empty or `null` to create an empty repository. | `string` | `"null"` | no | | [default\_branch](#input\_default\_branch) | Default branch name | `string` | `"main"` | no | | [description](#input\_description) | Short description of the repository | `string` | `""` | no | | [forgejo\_base\_url](#input\_forgejo\_base\_url) | STACKIT Git base URL | `string` | `"https://git-service.git.onstackit.cloud"` | no | diff --git a/modules/stackit/git-repository/buildingblock/main.tf b/modules/stackit/git-repository/buildingblock/main.tf index b8c9ad12..b00d0e4d 100644 --- a/modules/stackit/git-repository/buildingblock/main.tf +++ b/modules/stackit/git-repository/buildingblock/main.tf @@ -14,3 +14,11 @@ resource "forgejo_repository" "repository" { clone_addr = local.have_clone_addr ? var.clone_addr : null mirror = false } + +resource "forgejo_repository_action_secret" "action_secrets" { + for_each = var.action_secrets + + repository_id = forgejo_repository.repository.id + name = each.key + data = each.value +} diff --git a/modules/stackit/git-repository/buildingblock/variables.tf b/modules/stackit/git-repository/buildingblock/variables.tf index c6d467c8..c0ca2012 100644 --- a/modules/stackit/git-repository/buildingblock/variables.tf +++ b/modules/stackit/git-repository/buildingblock/variables.tf @@ -17,6 +17,18 @@ variable "forgejo_organization" { description = "STACKIT Git organization where the repository will be created" } +variable "action_secrets" { + type = map(string) + description = "Map of Forgejo Actions secrets to create in the repository." + sensitive = false # the whole map is not sensitive, but map values are! + default = {} + + validation { + condition = alltrue([for key in keys(var.action_secrets) : length(key) <= 30]) + error_message = "Forgejo Actions secret names must be 30 characters or less." + } +} + # ── User inputs (set per building block instance) ───────────────────────────── variable "name" { diff --git a/modules/stackit/git-repository/meshstack_integration.tf b/modules/stackit/git-repository/meshstack_integration.tf index f57d8906..152d1203 100644 --- a/modules/stackit/git-repository/meshstack_integration.tf +++ b/modules/stackit/git-repository/meshstack_integration.tf @@ -21,6 +21,17 @@ variable "forgejo_base_url" { type = string } +variable "action_secrets" { + type = map(string) + sensitive = false # the whole map is not sensitive, but map values are! + default = {} + + validation { + condition = alltrue([for key in keys(var.action_secrets) : length(key) <= 30]) + error_message = "Forgejo Actions secret names must be 30 characters or less." + } +} + variable "hub" { type = object({ git_ref = optional(string, "main") @@ -140,6 +151,18 @@ resource "meshstack_building_block_definition" "this" { assignment_type = "USER_INPUT" default_value = jsonencode("null") } + action_secrets = { + display_name = "Repository Action Secrets" + description = "Static sensitive map of Forgejo Actions secrets created in each provisioned repository." + type = "CODE" + assignment_type = "STATIC" + sensitive = { + argument = { + secret_value = jsonencode(var.action_secrets) + secret_version = nonsensitive(sha256(jsonencode(var.action_secrets))) + } + } + } } outputs = { From e970c7c6dd2737a4e1067aec6ae6f3a243abece2 Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:24:01 +0100 Subject: [PATCH 03/14] feat(ske): register forgejo connector as tenant building block Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../meshstack_integration.tf | 98 +++++++++++-------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/modules/ske/forgejo-connector/meshstack_integration.tf b/modules/ske/forgejo-connector/meshstack_integration.tf index 9511809a..7c7b9475 100644 --- a/modules/ske/forgejo-connector/meshstack_integration.tf +++ b/modules/ske/forgejo-connector/meshstack_integration.tf @@ -1,11 +1,10 @@ -# This file is an example showing how to register the STACKIT connector -# building block in a meshStack instance. +# This file registers the SKE Forgejo connector building block definition. terraform { required_providers { meshstack = { source = "meshcloud/meshstack" - version = "~> 0.19.0" + version = "~> 0.20.0" } } } @@ -48,6 +47,11 @@ variable "forgejo_api_token" { sensitive = true } +variable "forgejo_repo_definition_uuid" { + type = string + description = "UUID of the Forgejo repository building block definition used as parent dependency." +} + variable "harbor_host" { type = string description = "The URL of the Harbor registry." @@ -66,11 +70,6 @@ variable "harbor_password" { sensitive = true } -variable "forgejo_repo_definition_uuid" { - type = string - description = "The Building Block definition UUID of the repository parent." -} - variable "meshstack" { type = object({ owning_workspace_identifier = string @@ -91,13 +90,13 @@ variable "hub" { output "building_block_definition_version_ref" { value = var.hub.bbd_draft ? meshstack_building_block_definition.this.version_latest : meshstack_building_block_definition.this.version_latest_release - description = "Version of BBD is consumed in Building Block compositions, for example in the backplane of starter kits." + description = "Version of BBD is consumed in building block compositions." } module "backplane" { source = "./backplane" cluster_host = var.cluster_host - cluster_ca_certificate = var.client_certificate + cluster_ca_certificate = var.cluster_ca_certificate client_key = var.client_key client_certificate = var.client_certificate cluster_kubeconfig = var.cluster_kubeconfig @@ -109,11 +108,11 @@ resource "meshstack_building_block_definition" "this" { } spec = { - display_name = "STACKIT connector" - symbol = "data:image/png;base64,${filebase64("${path.module}/buildingblock/logo.png")}" - description = "Forgejo Actions Integration with STACKIT Kubernetes" + display_name = "SKE Forgejo Connector" + symbol = "https://raw.githubusercontent.com/meshcloud/meshstack-hub/${var.hub.git_ref}/modules/ske/forgejo-connector/buildingblock/logo.png" + description = "Connects a Forgejo repository with a tenant namespace on STACKIT SKE." support_url = "https://portal.stackit.cloud/git" - target_type = "WORKSPACE_LEVEL" + target_type = "TENANT_LEVEL" run_transparency = true } @@ -125,26 +124,25 @@ resource "meshstack_building_block_definition" "this" { terraform = { terraform_version = "1.9.0" repository_url = "https://github.com/meshcloud/meshstack-hub.git" - repository_path = "modules/stackit/git-connector/buildingblock" + repository_path = "modules/ske/forgejo-connector/buildingblock" ref_name = var.hub.git_ref async = false use_mesh_http_backend_fallback = true } } - dependency_refs = [{ uuid = "${var.forgejo_repo_definition_uuid}" }] + dependency_refs = [{ uuid = var.forgejo_repo_definition_uuid }] inputs = { - # ── Static inputs from backplane ────────────────────────────────────── - config_tf = { - display_name = "config_k8s" - description = "Static config for kubernetes" + "config.tf" = { + display_name = "config.tf" + description = "Static Kubernetes provider config and kubeconfig stub." type = "FILE" assignment_type = "STATIC" - is_environment = true sensitive = { argument = { - secret_value = jsonencode(module.backplane.config_tf) + secret_value = module.backplane.config_tf + secret_version = sha256(module.backplane.config_tf) } } } @@ -157,7 +155,8 @@ resource "meshstack_building_block_definition" "this" { is_environment = true sensitive = { argument = { - secret_value = jsonencode(var.forgejo_host) + secret_value = jsonencode(var.forgejo_host) + secret_version = sha256(jsonencode(var.forgejo_host)) } } } @@ -170,7 +169,8 @@ resource "meshstack_building_block_definition" "this" { is_environment = true sensitive = { argument = { - secret_value = jsonencode(var.forgejo_api_token) + secret_value = jsonencode(var.forgejo_api_token) + secret_version = sha256(jsonencode(var.forgejo_api_token)) } } } @@ -188,7 +188,12 @@ resource "meshstack_building_block_definition" "this" { description = "The username for the Harbor registry." type = "STRING" assignment_type = "STATIC" - argument = jsonencode(var.harbor_username) + sensitive = { + argument = { + secret_value = jsonencode(var.harbor_username) + secret_version = sha256(jsonencode(var.harbor_username)) + } + } } harbor_password = { @@ -198,38 +203,47 @@ resource "meshstack_building_block_definition" "this" { assignment_type = "STATIC" sensitive = { argument = { - secret_value = jsonencode(var.harbor_password) + secret_value = jsonencode(var.harbor_password) + secret_version = sha256(jsonencode(var.harbor_password)) } } } - forgejo_repository_name = { - display_name = "forgejo_repository_name" - description = "The name of the Forgejo repository." - type = "STRING" - assignment_type = "BUILDING_BLOCK_OUTPUT" - argument = "${var.forgejo_repo_definition_uuid}.repo_name" - } - - forgejo_repository_owner = { - display_name = "forgejo_repository_owner" - description = "The owner of the Forgejo repository." + repository_id = { + display_name = "repository_id" + description = "ID of the parent Forgejo repository where action secrets are created." type = "STRING" assignment_type = "BUILDING_BLOCK_OUTPUT" - argument = "${var.forgejo_repo_definition_uuid}.repo_owner" + argument = "${var.forgejo_repo_definition_uuid}.repository_id" } - # ── User inputs ──────────────────────────────────────────────────────── - namespace = { display_name = "namespace" description = "Associated namespace in kubernetes cluster." type = "STRING" + assignment_type = "PLATFORM_TENANT_ID" + } + + stage = { + display_name = "stage" + description = "Deployment stage used for secret suffixing (`dev` or `prod`)." + type = "STRING" + assignment_type = "USER_INPUT" + value_validation_regex = "^(dev|prod)$" + validation_regex_error_message = "Stage must be either 'dev' or 'prod'." + } + + additional_environment_variables = { + display_name = "additional_environment_variables" + description = "Map of additional key/value pairs to create as repository action secrets." + type = "CODE" assignment_type = "USER_INPUT" + default_value = jsonencode({}) } } - outputs = { - } + outputs = {} + + permissions = ["TENANT_LIST", "TENANT_SAVE", "TENANT_DELETE"] } } From 656d321c893b4984d1d2c83a77c9a686dd3fd391 Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:25:05 +0100 Subject: [PATCH 04/14] feat(ske): write stage-specific forgejo repo secrets Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../forgejo-connector/buildingblock/README.md | 6 ++--- .../buildingblock/forgejo.tf | 23 +++++++++++-------- .../buildingblock/variables.tf | 15 ++++++++---- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/modules/ske/forgejo-connector/buildingblock/README.md b/modules/ske/forgejo-connector/buildingblock/README.md index 396a213c..d87fa85e 100644 --- a/modules/ske/forgejo-connector/buildingblock/README.md +++ b/modules/ske/forgejo-connector/buildingblock/README.md @@ -58,24 +58,24 @@ No modules. | [forgejo_repository_action_secret.additional](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | | [forgejo_repository_action_secret.container_registry](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | | [forgejo_repository_action_secret.kubeconfig](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | +| [forgejo_repository_action_secret.namespace](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | | [kubernetes_cluster_role_binding.forgejo_actions_clusterissuer_access](https://registry.terraform.io/providers/hashicorp/kubernetes/2.35.1/docs/resources/cluster_role_binding) | resource | | [kubernetes_role_binding.forgejo_actions](https://registry.terraform.io/providers/hashicorp/kubernetes/2.35.1/docs/resources/role_binding) | resource | | [kubernetes_secret.forgejo_actions](https://registry.terraform.io/providers/hashicorp/kubernetes/2.35.1/docs/resources/secret) | resource | | [kubernetes_secret.image_pull](https://registry.terraform.io/providers/hashicorp/kubernetes/2.35.1/docs/resources/secret) | resource | | [kubernetes_service_account.forgejo_actions](https://registry.terraform.io/providers/hashicorp/kubernetes/2.35.1/docs/resources/service_account) | resource | -| [forgejo_repository.this](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/data-sources/repository) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [additional\_environment\_variables](#input\_additional\_environment\_variables) | Map of additional environment variable key/value pairs to set as Forgejo repository action secrets. | `map(string)` | `{}` | no | -| [forgejo\_repository\_name](#input\_forgejo\_repository\_name) | The name of the Forgejo repository. | `string` | n/a | yes | -| [forgejo\_repository\_owner](#input\_forgejo\_repository\_owner) | The owner of the Forgejo repository. | `string` | n/a | yes | | [harbor\_host](#input\_harbor\_host) | The URL of the Harbor registry. | `string` | `"https://registry.onstackit.cloud"` | no | | [harbor\_password](#input\_harbor\_password) | The password for the Harbor registry. | `string` | n/a | yes | | [harbor\_username](#input\_harbor\_username) | The username for the Harbor registry. | `string` | n/a | yes | | [namespace](#input\_namespace) | Associated namespace in kubernetes cluster. | `string` | n/a | yes | +| [repository\_id](#input\_repository\_id) | The ID of the Forgejo repository. | `string` | n/a | yes | +| [stage](#input\_stage) | Deployment stage used for secret suffixing (`dev` or `prod`). | `string` | n/a | yes | ## Outputs diff --git a/modules/ske/forgejo-connector/buildingblock/forgejo.tf b/modules/ske/forgejo-connector/buildingblock/forgejo.tf index 1498319f..162a5fe5 100644 --- a/modules/ske/forgejo-connector/buildingblock/forgejo.tf +++ b/modules/ske/forgejo-connector/buildingblock/forgejo.tf @@ -1,4 +1,6 @@ locals { + stage_suffix = upper(var.stage) + kubeconfig_user = { users = [ { @@ -23,17 +25,18 @@ locals { kubeconfig = merge(local.stackit_kubeconfig_stub, local.kubeconfig_user) } -data "forgejo_repository" "this" { - name = var.forgejo_repository_name - owner = var.forgejo_repository_owner -} - resource "forgejo_repository_action_secret" "kubeconfig" { - repository_id = data.forgejo_repository.this.id - name = "KUBECONFIG" + repository_id = var.repository_id + name = "KUBECONFIG_${local.stage_suffix}" data = yamlencode(local.kubeconfig) } +resource "forgejo_repository_action_secret" "namespace" { + repository_id = var.repository_id + name = "K8S_NAMESPACE_${local.stage_suffix}" + data = var.namespace +} + resource "forgejo_repository_action_secret" "container_registry" { for_each = { HOST = var.harbor_host @@ -41,7 +44,7 @@ resource "forgejo_repository_action_secret" "container_registry" { PASSWORD = var.harbor_password } - repository_id = data.forgejo_repository.this.id + repository_id = var.repository_id name = "STACKIT_HARBOR_${each.key}" data = each.value } @@ -49,7 +52,7 @@ resource "forgejo_repository_action_secret" "container_registry" { resource "forgejo_repository_action_secret" "additional" { for_each = var.additional_environment_variables - repository_id = data.forgejo_repository.this.id + repository_id = var.repository_id name = each.key data = each.value -} \ No newline at end of file +} diff --git a/modules/ske/forgejo-connector/buildingblock/variables.tf b/modules/ske/forgejo-connector/buildingblock/variables.tf index 537e202d..d5e0bd9a 100644 --- a/modules/ske/forgejo-connector/buildingblock/variables.tf +++ b/modules/ske/forgejo-connector/buildingblock/variables.tf @@ -16,14 +16,19 @@ variable "harbor_password" { sensitive = true } -variable "forgejo_repository_name" { +variable "repository_id" { type = string - description = "The name of the Forgejo repository." + description = "The ID of the Forgejo repository." } -variable "forgejo_repository_owner" { +variable "stage" { type = string - description = "The owner of the Forgejo repository." + description = "Deployment stage used for secret suffixing (`dev` or `prod`)." + + validation { + condition = can(regex("^(dev|prod)$", var.stage)) + error_message = "stage must be either 'dev' or 'prod'." + } } variable "additional_environment_variables" { @@ -35,4 +40,4 @@ variable "additional_environment_variables" { variable "namespace" { description = "Associated namespace in kubernetes cluster." type = string -} \ No newline at end of file +} From dafa0df083345fadb884edd447deb3fcc7e0f402 Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:25:54 +0100 Subject: [PATCH 05/14] feat(ske): compose tenant forgejo connectors in starterkit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ske-starterkit/buildingblock/README.md | 2 ++ .../ske/ske-starterkit/buildingblock/main.tf | 29 +++++++++++++++++++ .../ske-starterkit/buildingblock/variables.tf | 5 ++++ 3 files changed, 36 insertions(+) diff --git a/modules/ske/ske-starterkit/buildingblock/README.md b/modules/ske/ske-starterkit/buildingblock/README.md index 1296cd20..e517a433 100644 --- a/modules/ske/ske-starterkit/buildingblock/README.md +++ b/modules/ske/ske-starterkit/buildingblock/README.md @@ -24,6 +24,7 @@ No modules. | Name | Type | |------|------| +| [meshstack_building_block_v2.forgejo_connector](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/building_block_v2) | resource | | [meshstack_building_block_v2.git_repository](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/building_block_v2) | resource | | [meshstack_project.this](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/project) | resource | | [meshstack_project_user_binding.creator_to_admin](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/project_user_binding) | resource | @@ -36,6 +37,7 @@ No modules. | [building\_block\_definition\_version\_refs](#input\_building\_block\_definition\_version\_refs) | n/a | `map(object({ uuid = string }))` | n/a | yes | | [creator](#input\_creator) | Information about the creator of the resources who will be assigned Project Admin role |
object({
type = string
identifier = string
displayName = string
username = optional(string)
email = optional(string)
euid = optional(string)
})
| n/a | yes | | [full\_platform\_identifier](#input\_full\_platform\_identifier) | Full platform identifier of the SKE platform. | `string` | n/a | yes | +| [git\_repository\_definition\_uuid](#input\_git\_repository\_definition\_uuid) | Definition UUID of the composed git-repository building block. | `string` | n/a | yes | | [landing\_zone\_identifiers](#input\_landing\_zone\_identifiers) | SKE Landing zone identifiers for the dev/prod meshTenant. |
object({
dev = string
prod = string
})
| n/a | yes | | [name](#input\_name) | This name will be used for the created projects. | `string` | n/a | yes | | [project\_tags](#input\_project\_tags) | Tags for dev/prod meshProject. |
object({
dev : map(list(string))
prod : map(list(string))

owner_tag_key = optional(string, null)
})
| n/a | yes | diff --git a/modules/ske/ske-starterkit/buildingblock/main.tf b/modules/ske/ske-starterkit/buildingblock/main.tf index 1a8801a4..e91dab3f 100644 --- a/modules/ske/ske-starterkit/buildingblock/main.tf +++ b/modules/ske/ske-starterkit/buildingblock/main.tf @@ -66,3 +66,32 @@ resource "meshstack_tenant_v4" "this" { landing_zone_identifier = each.value } } + +resource "meshstack_building_block_v2" "forgejo_connector" { + for_each = meshstack_tenant_v4.this + + depends_on = [meshstack_building_block_v2.git_repository] + + spec = { + building_block_definition_version_ref = var.building_block_definition_version_refs["forgejo-connector"] + + display_name = "${var.name} Forgejo Connector ${upper(each.key)}" + target_ref = { + kind = "meshTenant" + uuid = each.value.metadata.uuid + } + + parent_building_blocks = [{ + buildingblock_uuid = meshstack_building_block_v2.git_repository.metadata.uuid + definition_uuid = var.git_repository_definition_uuid + }] + + inputs = { + stage = { + value_string = each.key + } + } + } + + wait_for_completion = true +} diff --git a/modules/ske/ske-starterkit/buildingblock/variables.tf b/modules/ske/ske-starterkit/buildingblock/variables.tf index d0628fc5..53148869 100644 --- a/modules/ske/ske-starterkit/buildingblock/variables.tf +++ b/modules/ske/ske-starterkit/buildingblock/variables.tf @@ -50,3 +50,8 @@ variable "repo_clone_addr" { variable "building_block_definition_version_refs" { type = map(object({ uuid = string })) } + +variable "git_repository_definition_uuid" { + type = string + description = "Definition UUID of the composed git-repository building block." +} From b4b7b763db5a06f1c38bd7552cbeb2c042c36ccc Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:26:38 +0100 Subject: [PATCH 06/14] feat(ske): pass git repository definition uuid to starterkit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- modules/ske/ske-starterkit/meshstack_integration.tf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/ske/ske-starterkit/meshstack_integration.tf b/modules/ske/ske-starterkit/meshstack_integration.tf index 095fb109..8e554b9e 100644 --- a/modules/ske/ske-starterkit/meshstack_integration.tf +++ b/modules/ske/ske-starterkit/meshstack_integration.tf @@ -49,6 +49,11 @@ variable "building_block_definition_version_refs" { })) } +variable "git_repository_definition_uuid" { + type = string + description = "Definition UUID of the STACKIT git-repository building block." +} + variable "hub" { type = object({ git_ref = optional(string, "main") @@ -202,6 +207,13 @@ EOT } } } + "git_repository_definition_uuid" = { + assignment_type = "STATIC" + type = "STRING" + display_name = "Git Repository Definition UUID" + description = "Definition UUID used for parent dependency wiring to the composed git-repository." + argument = jsonencode(var.git_repository_definition_uuid) + } } outputs = {} From 56326a4ae8460401cf44ee391e4298eca7783521 Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:28:06 +0100 Subject: [PATCH 07/14] feat(stackit): expose git-repository definition uuid output Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- modules/stackit/git-repository/meshstack_integration.tf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/stackit/git-repository/meshstack_integration.tf b/modules/stackit/git-repository/meshstack_integration.tf index 152d1203..16b554e7 100644 --- a/modules/stackit/git-repository/meshstack_integration.tf +++ b/modules/stackit/git-repository/meshstack_integration.tf @@ -49,6 +49,11 @@ output "building_block_definition_version_ref" { description = "Version of BBD is consumed in Building Block compositions, for example in the backplane of starter kits." } +output "building_block_definition_uuid" { + value = meshstack_building_block_definition.this.ref.uuid + description = "UUID of the STACKIT Git Repository building block definition." +} + module "backplane" { source = "github.com/meshcloud/meshstack-hub//modules/stackit/git-repository/backplane?ref=a3843c80c76c4a0298769eea8d93807bb2b271fc" From 1236697f6712ad5d053fad4c0d94cf7a760abe2b Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:29:54 +0100 Subject: [PATCH 08/14] fix(ske): use harbor vars for image pull secret auth Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ske/forgejo-connector/buildingblock/kubernetes.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/ske/forgejo-connector/buildingblock/kubernetes.tf b/modules/ske/forgejo-connector/buildingblock/kubernetes.tf index dae6cb31..f57e3be8 100644 --- a/modules/ske/forgejo-connector/buildingblock/kubernetes.tf +++ b/modules/ske/forgejo-connector/buildingblock/kubernetes.tf @@ -65,12 +65,12 @@ resource "kubernetes_secret" "image_pull" { data = { ".dockerconfigjson" = jsonencode({ auths = { - "${local.harbor.host}" = { - username = local.harbor.username - password = local.harbor.password - auth = base64encode("${local.harbor.username}:${local.harbor.password}") + "${var.harbor_host}" = { + username = var.harbor_username + password = var.harbor_password + auth = base64encode("${var.harbor_username}:${var.harbor_password}") } } }) } -} \ No newline at end of file +} From 63895488f0bfd6a76cae3848604995ca2207ed17 Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:30:38 +0100 Subject: [PATCH 09/14] fix(ske): declare supported platform for tenant connector Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ske/forgejo-connector/meshstack_integration.tf | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/ske/forgejo-connector/meshstack_integration.tf b/modules/ske/forgejo-connector/meshstack_integration.tf index 7c7b9475..ae35eebc 100644 --- a/modules/ske/forgejo-connector/meshstack_integration.tf +++ b/modules/ske/forgejo-connector/meshstack_integration.tf @@ -108,12 +108,13 @@ resource "meshstack_building_block_definition" "this" { } spec = { - display_name = "SKE Forgejo Connector" - symbol = "https://raw.githubusercontent.com/meshcloud/meshstack-hub/${var.hub.git_ref}/modules/ske/forgejo-connector/buildingblock/logo.png" - description = "Connects a Forgejo repository with a tenant namespace on STACKIT SKE." - support_url = "https://portal.stackit.cloud/git" - target_type = "TENANT_LEVEL" - run_transparency = true + display_name = "SKE Forgejo Connector" + symbol = "https://raw.githubusercontent.com/meshcloud/meshstack-hub/${var.hub.git_ref}/modules/ske/forgejo-connector/buildingblock/logo.png" + description = "Connects a Forgejo repository with a tenant namespace on STACKIT SKE." + support_url = "https://portal.stackit.cloud/git" + target_type = "TENANT_LEVEL" + supported_platforms = [{ name = "STACKIT_KUBERNETES_ENGINE" }] + run_transparency = true } version_spec = { From 32fb777c71c913cf9b13566cada6b8afc1e7722d Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:36:05 +0100 Subject: [PATCH 10/14] refactor(ske): drop obsolete git repository definition input Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- modules/ske/ske-starterkit/buildingblock/README.md | 1 - modules/ske/ske-starterkit/buildingblock/main.tf | 4 +--- .../ske/ske-starterkit/buildingblock/variables.tf | 5 ----- modules/ske/ske-starterkit/meshstack_integration.tf | 12 ------------ 4 files changed, 1 insertion(+), 21 deletions(-) diff --git a/modules/ske/ske-starterkit/buildingblock/README.md b/modules/ske/ske-starterkit/buildingblock/README.md index e517a433..acbf4e59 100644 --- a/modules/ske/ske-starterkit/buildingblock/README.md +++ b/modules/ske/ske-starterkit/buildingblock/README.md @@ -37,7 +37,6 @@ No modules. | [building\_block\_definition\_version\_refs](#input\_building\_block\_definition\_version\_refs) | n/a | `map(object({ uuid = string }))` | n/a | yes | | [creator](#input\_creator) | Information about the creator of the resources who will be assigned Project Admin role |
object({
type = string
identifier = string
displayName = string
username = optional(string)
email = optional(string)
euid = optional(string)
})
| n/a | yes | | [full\_platform\_identifier](#input\_full\_platform\_identifier) | Full platform identifier of the SKE platform. | `string` | n/a | yes | -| [git\_repository\_definition\_uuid](#input\_git\_repository\_definition\_uuid) | Definition UUID of the composed git-repository building block. | `string` | n/a | yes | | [landing\_zone\_identifiers](#input\_landing\_zone\_identifiers) | SKE Landing zone identifiers for the dev/prod meshTenant. |
object({
dev = string
prod = string
})
| n/a | yes | | [name](#input\_name) | This name will be used for the created projects. | `string` | n/a | yes | | [project\_tags](#input\_project\_tags) | Tags for dev/prod meshProject. |
object({
dev : map(list(string))
prod : map(list(string))

owner_tag_key = optional(string, null)
})
| n/a | yes | diff --git a/modules/ske/ske-starterkit/buildingblock/main.tf b/modules/ske/ske-starterkit/buildingblock/main.tf index e91dab3f..5b166344 100644 --- a/modules/ske/ske-starterkit/buildingblock/main.tf +++ b/modules/ske/ske-starterkit/buildingblock/main.tf @@ -70,8 +70,6 @@ resource "meshstack_tenant_v4" "this" { resource "meshstack_building_block_v2" "forgejo_connector" { for_each = meshstack_tenant_v4.this - depends_on = [meshstack_building_block_v2.git_repository] - spec = { building_block_definition_version_ref = var.building_block_definition_version_refs["forgejo-connector"] @@ -83,7 +81,7 @@ resource "meshstack_building_block_v2" "forgejo_connector" { parent_building_blocks = [{ buildingblock_uuid = meshstack_building_block_v2.git_repository.metadata.uuid - definition_uuid = var.git_repository_definition_uuid + definition_uuid = meshstack_building_block_v2.git_repository.spec.building_block_definition_version_ref.uuid }] inputs = { diff --git a/modules/ske/ske-starterkit/buildingblock/variables.tf b/modules/ske/ske-starterkit/buildingblock/variables.tf index 53148869..d0628fc5 100644 --- a/modules/ske/ske-starterkit/buildingblock/variables.tf +++ b/modules/ske/ske-starterkit/buildingblock/variables.tf @@ -50,8 +50,3 @@ variable "repo_clone_addr" { variable "building_block_definition_version_refs" { type = map(object({ uuid = string })) } - -variable "git_repository_definition_uuid" { - type = string - description = "Definition UUID of the composed git-repository building block." -} diff --git a/modules/ske/ske-starterkit/meshstack_integration.tf b/modules/ske/ske-starterkit/meshstack_integration.tf index 8e554b9e..095fb109 100644 --- a/modules/ske/ske-starterkit/meshstack_integration.tf +++ b/modules/ske/ske-starterkit/meshstack_integration.tf @@ -49,11 +49,6 @@ variable "building_block_definition_version_refs" { })) } -variable "git_repository_definition_uuid" { - type = string - description = "Definition UUID of the STACKIT git-repository building block." -} - variable "hub" { type = object({ git_ref = optional(string, "main") @@ -207,13 +202,6 @@ EOT } } } - "git_repository_definition_uuid" = { - assignment_type = "STATIC" - type = "STRING" - display_name = "Git Repository Definition UUID" - description = "Definition UUID used for parent dependency wiring to the composed git-repository." - argument = jsonencode(var.git_repository_definition_uuid) - } } outputs = {} From 0cd74b4dfde4884d3ca2499c79740890b183d9ef Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:39:57 +0100 Subject: [PATCH 11/14] chore(ske): commit pending forgejo connector adjustments Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- modules/ske/forgejo-connector/meshstack_integration.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ske/forgejo-connector/meshstack_integration.tf b/modules/ske/forgejo-connector/meshstack_integration.tf index ae35eebc..997a0794 100644 --- a/modules/ske/forgejo-connector/meshstack_integration.tf +++ b/modules/ske/forgejo-connector/meshstack_integration.tf @@ -215,7 +215,7 @@ resource "meshstack_building_block_definition" "this" { description = "ID of the parent Forgejo repository where action secrets are created." type = "STRING" assignment_type = "BUILDING_BLOCK_OUTPUT" - argument = "${var.forgejo_repo_definition_uuid}.repository_id" + argument = jsonencode("${var.forgejo_repo_definition_uuid}.repository_id") } namespace = { From 3a3a7929755bc3a8957ff4fa65da5b089ddf2a01 Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:41:54 +0100 Subject: [PATCH 12/14] refactor(ske): remove unused additional connector env vars Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- modules/ske/forgejo-connector/buildingblock/README.md | 2 -- modules/ske/forgejo-connector/buildingblock/forgejo.tf | 8 -------- modules/ske/forgejo-connector/buildingblock/variables.tf | 6 ------ modules/ske/forgejo-connector/meshstack_integration.tf | 7 ------- 4 files changed, 23 deletions(-) diff --git a/modules/ske/forgejo-connector/buildingblock/README.md b/modules/ske/forgejo-connector/buildingblock/README.md index d87fa85e..a0015d67 100644 --- a/modules/ske/forgejo-connector/buildingblock/README.md +++ b/modules/ske/forgejo-connector/buildingblock/README.md @@ -55,7 +55,6 @@ No modules. | Name | Type | |------|------| -| [forgejo_repository_action_secret.additional](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | | [forgejo_repository_action_secret.container_registry](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | | [forgejo_repository_action_secret.kubeconfig](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | | [forgejo_repository_action_secret.namespace](https://registry.terraform.io/providers/svalabs/forgejo/latest/docs/resources/repository_action_secret) | resource | @@ -69,7 +68,6 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [additional\_environment\_variables](#input\_additional\_environment\_variables) | Map of additional environment variable key/value pairs to set as Forgejo repository action secrets. | `map(string)` | `{}` | no | | [harbor\_host](#input\_harbor\_host) | The URL of the Harbor registry. | `string` | `"https://registry.onstackit.cloud"` | no | | [harbor\_password](#input\_harbor\_password) | The password for the Harbor registry. | `string` | n/a | yes | | [harbor\_username](#input\_harbor\_username) | The username for the Harbor registry. | `string` | n/a | yes | diff --git a/modules/ske/forgejo-connector/buildingblock/forgejo.tf b/modules/ske/forgejo-connector/buildingblock/forgejo.tf index 162a5fe5..e7033937 100644 --- a/modules/ske/forgejo-connector/buildingblock/forgejo.tf +++ b/modules/ske/forgejo-connector/buildingblock/forgejo.tf @@ -48,11 +48,3 @@ resource "forgejo_repository_action_secret" "container_registry" { name = "STACKIT_HARBOR_${each.key}" data = each.value } - -resource "forgejo_repository_action_secret" "additional" { - for_each = var.additional_environment_variables - - repository_id = var.repository_id - name = each.key - data = each.value -} diff --git a/modules/ske/forgejo-connector/buildingblock/variables.tf b/modules/ske/forgejo-connector/buildingblock/variables.tf index d5e0bd9a..9f60702a 100644 --- a/modules/ske/forgejo-connector/buildingblock/variables.tf +++ b/modules/ske/forgejo-connector/buildingblock/variables.tf @@ -31,12 +31,6 @@ variable "stage" { } } -variable "additional_environment_variables" { - type = map(string) - description = "Map of additional environment variable key/value pairs to set as Forgejo repository action secrets." - default = {} -} - variable "namespace" { description = "Associated namespace in kubernetes cluster." type = string diff --git a/modules/ske/forgejo-connector/meshstack_integration.tf b/modules/ske/forgejo-connector/meshstack_integration.tf index 997a0794..d0c57986 100644 --- a/modules/ske/forgejo-connector/meshstack_integration.tf +++ b/modules/ske/forgejo-connector/meshstack_integration.tf @@ -234,13 +234,6 @@ resource "meshstack_building_block_definition" "this" { validation_regex_error_message = "Stage must be either 'dev' or 'prod'." } - additional_environment_variables = { - display_name = "additional_environment_variables" - description = "Map of additional key/value pairs to create as repository action secrets." - type = "CODE" - assignment_type = "USER_INPUT" - default_value = jsonencode({}) - } } outputs = {} From d4eb0abd8f81deb4cea1d42407f4a75ea4d3ce3d Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Mon, 16 Mar 2026 21:46:08 +0100 Subject: [PATCH 13/14] fix(ske): restore kubeconfig stub and file input wiring Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../forgejo-connector/backplane/outputs.tf | 20 +------------------ .../forgejo-connector/buildingblock/README.md | 2 ++ .../buildingblock/forgejo.tf | 15 ++++++++++++++ .../buildingblock/variables.tf | 10 ++++++++++ .../meshstack_integration.tf | 18 ++++++++++++++++- 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/modules/ske/forgejo-connector/backplane/outputs.tf b/modules/ske/forgejo-connector/backplane/outputs.tf index cb7b901a..fd6330c0 100644 --- a/modules/ske/forgejo-connector/backplane/outputs.tf +++ b/modules/ske/forgejo-connector/backplane/outputs.tf @@ -8,23 +8,5 @@ output "config_tf" { client_certificate = base64decode("${var.client_certificate}") client_key = base64decode("${var.client_key}") } - - locals { - stackit_kubeconfig_stub = { - apiVersion = "v1" - kind = "Config" - current-context = "stackit_k8s" - - clusters = [ - { - name = "stackit_k8s" - cluster = { - server = "${var.cluster_host}" - certificate-authority-data = "${var.cluster_ca_certificate}" - } - } - ] - } - } EOF -} \ No newline at end of file +} diff --git a/modules/ske/forgejo-connector/buildingblock/README.md b/modules/ske/forgejo-connector/buildingblock/README.md index a0015d67..d5947bb1 100644 --- a/modules/ske/forgejo-connector/buildingblock/README.md +++ b/modules/ske/forgejo-connector/buildingblock/README.md @@ -68,6 +68,8 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [cluster\_ca\_certificate](#input\_cluster\_ca\_certificate) | Base64-encoded Kubernetes cluster CA certificate used for generated kubeconfig. | `string` | n/a | yes | +| [cluster\_host](#input\_cluster\_host) | Kubernetes API server URL used for generated kubeconfig. | `string` | n/a | yes | | [harbor\_host](#input\_harbor\_host) | The URL of the Harbor registry. | `string` | `"https://registry.onstackit.cloud"` | no | | [harbor\_password](#input\_harbor\_password) | The password for the Harbor registry. | `string` | n/a | yes | | [harbor\_username](#input\_harbor\_username) | The username for the Harbor registry. | `string` | n/a | yes | diff --git a/modules/ske/forgejo-connector/buildingblock/forgejo.tf b/modules/ske/forgejo-connector/buildingblock/forgejo.tf index e7033937..1e2184fe 100644 --- a/modules/ske/forgejo-connector/buildingblock/forgejo.tf +++ b/modules/ske/forgejo-connector/buildingblock/forgejo.tf @@ -1,5 +1,20 @@ locals { stage_suffix = upper(var.stage) + stackit_kubeconfig_stub = { + apiVersion = "v1" + kind = "Config" + current-context = "stackit_k8s" + + clusters = [ + { + name = "stackit_k8s" + cluster = { + server = var.cluster_host + certificate-authority-data = var.cluster_ca_certificate + } + } + ] + } kubeconfig_user = { users = [ diff --git a/modules/ske/forgejo-connector/buildingblock/variables.tf b/modules/ske/forgejo-connector/buildingblock/variables.tf index 9f60702a..c04575aa 100644 --- a/modules/ske/forgejo-connector/buildingblock/variables.tf +++ b/modules/ske/forgejo-connector/buildingblock/variables.tf @@ -4,6 +4,16 @@ variable "harbor_host" { default = "https://registry.onstackit.cloud" } +variable "cluster_host" { + type = string + description = "Kubernetes API server URL used for generated kubeconfig." +} + +variable "cluster_ca_certificate" { + type = string + description = "Base64-encoded Kubernetes cluster CA certificate used for generated kubeconfig." +} + variable "harbor_username" { type = string description = "The username for the Harbor registry." diff --git a/modules/ske/forgejo-connector/meshstack_integration.tf b/modules/ske/forgejo-connector/meshstack_integration.tf index d0c57986..7f734d4e 100644 --- a/modules/ske/forgejo-connector/meshstack_integration.tf +++ b/modules/ske/forgejo-connector/meshstack_integration.tf @@ -142,7 +142,7 @@ resource "meshstack_building_block_definition" "this" { assignment_type = "STATIC" sensitive = { argument = { - secret_value = module.backplane.config_tf + secret_value = "data:application/octet-stream;base64,${base64encode(module.backplane.config_tf)}" secret_version = sha256(module.backplane.config_tf) } } @@ -184,6 +184,22 @@ resource "meshstack_building_block_definition" "this" { argument = jsonencode(var.harbor_host) } + cluster_host = { + display_name = "cluster_host" + description = "Kubernetes API server URL used for generated kubeconfig." + type = "STRING" + assignment_type = "STATIC" + argument = jsonencode(var.cluster_host) + } + + cluster_ca_certificate = { + display_name = "cluster_ca_certificate" + description = "Base64-encoded Kubernetes cluster CA certificate used for generated kubeconfig." + type = "STRING" + assignment_type = "STATIC" + argument = jsonencode(var.cluster_ca_certificate) + } + harbor_username = { display_name = "harbor_username" description = "The username for the Harbor registry." From 2ca4690590a7c0165b58e1db1a5637065d41848f Mon Sep 17 00:00:00 2001 From: Andreas Grub Date: Tue, 17 Mar 2026 14:24:21 +0100 Subject: [PATCH 14/14] feat(ske): rework forgejo connector kubeconfig wiring - remove cluster_kubeconfig from backplane interface\n- add encrypted CODE kubeconfig input in BBD\n- pass kubeconfig_cluster_name from backplane output\n- build KUBECONFIG secret from kubeconfig + generated user/context\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ske/forgejo-connector/backplane/README.md | 4 ++-- .../forgejo-connector/backplane/outputs.tf | 5 ++++ .../forgejo-connector/backplane/variables.tf | 6 ----- .../forgejo-connector/buildingblock/README.md | 4 ++-- .../buildingblock/forgejo.tf | 23 ++++-------------- .../buildingblock/variables.tf | 11 +++++---- .../meshstack_integration.tf | 24 +++++++++++-------- 7 files changed, 34 insertions(+), 43 deletions(-) diff --git a/modules/ske/forgejo-connector/backplane/README.md b/modules/ske/forgejo-connector/backplane/README.md index d94e3806..b0b41b53 100644 --- a/modules/ske/forgejo-connector/backplane/README.md +++ b/modules/ske/forgejo-connector/backplane/README.md @@ -28,11 +28,11 @@ No resources. | [client\_key](#input\_client\_key) | Base64-encoded private key corresponding to the client certificate, used for authentication with the Kubernetes API server. | `string` | n/a | yes | | [cluster\_ca\_certificate](#input\_cluster\_ca\_certificate) | Base64-encoded certificate authority (CA) certificate used to verify the Kubernetes API server's identity. | `string` | n/a | yes | | [cluster\_host](#input\_cluster\_host) | The endpoint of the Kubernetes cluster. | `string` | n/a | yes | -| [cluster\_kubeconfig](#input\_cluster\_kubeconfig) | Raw kubeconfig content containing the configuration required to access and authenticate to the Kubernetes cluster. | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| | [config\_tf](#output\_config\_tf) | Generates a config.tf that can be dropped into meshStack's BuildingBlockDefinition as an encrypted file input to configure this building block. | - \ No newline at end of file +| [kubeconfig\_cluster\_name](#output\_kubeconfig\_cluster\_name) | Cluster name to use when merging static kubeconfig and generated service-account credentials. | + diff --git a/modules/ske/forgejo-connector/backplane/outputs.tf b/modules/ske/forgejo-connector/backplane/outputs.tf index fd6330c0..326522c4 100644 --- a/modules/ske/forgejo-connector/backplane/outputs.tf +++ b/modules/ske/forgejo-connector/backplane/outputs.tf @@ -10,3 +10,8 @@ output "config_tf" { } EOF } + +output "kubeconfig_cluster_name" { + description = "Cluster name to use when merging static kubeconfig and generated service-account credentials." + value = "stackit_k8s" +} diff --git a/modules/ske/forgejo-connector/backplane/variables.tf b/modules/ske/forgejo-connector/backplane/variables.tf index 83013d1f..08eaf08e 100644 --- a/modules/ske/forgejo-connector/backplane/variables.tf +++ b/modules/ske/forgejo-connector/backplane/variables.tf @@ -20,9 +20,3 @@ variable "client_key" { type = string sensitive = true } - -variable "cluster_kubeconfig" { - description = "Raw kubeconfig content containing the configuration required to access and authenticate to the Kubernetes cluster." - type = string - sensitive = true -} \ No newline at end of file diff --git a/modules/ske/forgejo-connector/buildingblock/README.md b/modules/ske/forgejo-connector/buildingblock/README.md index d5947bb1..09f52164 100644 --- a/modules/ske/forgejo-connector/buildingblock/README.md +++ b/modules/ske/forgejo-connector/buildingblock/README.md @@ -68,11 +68,11 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [cluster\_ca\_certificate](#input\_cluster\_ca\_certificate) | Base64-encoded Kubernetes cluster CA certificate used for generated kubeconfig. | `string` | n/a | yes | -| [cluster\_host](#input\_cluster\_host) | Kubernetes API server URL used for generated kubeconfig. | `string` | n/a | yes | | [harbor\_host](#input\_harbor\_host) | The URL of the Harbor registry. | `string` | `"https://registry.onstackit.cloud"` | no | | [harbor\_password](#input\_harbor\_password) | The password for the Harbor registry. | `string` | n/a | yes | | [harbor\_username](#input\_harbor\_username) | The username for the Harbor registry. | `string` | n/a | yes | +| [kubeconfig](#input\_kubeconfig) | Static kubeconfig content of the SKE cluster. | `any` | n/a | yes | +| [kubeconfig\_cluster\_name](#input\_kubeconfig\_cluster\_name) | Cluster name used in merged kubeconfig context entries. | `string` | n/a | yes | | [namespace](#input\_namespace) | Associated namespace in kubernetes cluster. | `string` | n/a | yes | | [repository\_id](#input\_repository\_id) | The ID of the Forgejo repository. | `string` | n/a | yes | | [stage](#input\_stage) | Deployment stage used for secret suffixing (`dev` or `prod`). | `string` | n/a | yes | diff --git a/modules/ske/forgejo-connector/buildingblock/forgejo.tf b/modules/ske/forgejo-connector/buildingblock/forgejo.tf index 1e2184fe..e55d29c8 100644 --- a/modules/ske/forgejo-connector/buildingblock/forgejo.tf +++ b/modules/ske/forgejo-connector/buildingblock/forgejo.tf @@ -1,22 +1,9 @@ locals { stage_suffix = upper(var.stage) - stackit_kubeconfig_stub = { - apiVersion = "v1" - kind = "Config" - current-context = "stackit_k8s" - - clusters = [ - { - name = "stackit_k8s" - cluster = { - server = var.cluster_host - certificate-authority-data = var.cluster_ca_certificate - } - } - ] - } kubeconfig_user = { + current-context = var.kubeconfig_cluster_name + users = [ { name = kubernetes_service_account.forgejo_actions.metadata[0].name @@ -28,16 +15,16 @@ locals { contexts = [ { - name = "stackit_k8s" + name = var.kubeconfig_cluster_name context = { - cluster = "stackit_k8s" + cluster = var.kubeconfig_cluster_name namespace = var.namespace user = kubernetes_service_account.forgejo_actions.metadata[0].name } } ] } - kubeconfig = merge(local.stackit_kubeconfig_stub, local.kubeconfig_user) + kubeconfig = merge(var.kubeconfig, local.kubeconfig_user) } resource "forgejo_repository_action_secret" "kubeconfig" { diff --git a/modules/ske/forgejo-connector/buildingblock/variables.tf b/modules/ske/forgejo-connector/buildingblock/variables.tf index c04575aa..f62fae60 100644 --- a/modules/ske/forgejo-connector/buildingblock/variables.tf +++ b/modules/ske/forgejo-connector/buildingblock/variables.tf @@ -4,14 +4,15 @@ variable "harbor_host" { default = "https://registry.onstackit.cloud" } -variable "cluster_host" { - type = string - description = "Kubernetes API server URL used for generated kubeconfig." +variable "kubeconfig" { + type = any + description = "Static kubeconfig content of the SKE cluster." + sensitive = true } -variable "cluster_ca_certificate" { +variable "kubeconfig_cluster_name" { type = string - description = "Base64-encoded Kubernetes cluster CA certificate used for generated kubeconfig." + description = "Cluster name used in merged kubeconfig context entries." } variable "harbor_username" { diff --git a/modules/ske/forgejo-connector/meshstack_integration.tf b/modules/ske/forgejo-connector/meshstack_integration.tf index 7f734d4e..f3a8d282 100644 --- a/modules/ske/forgejo-connector/meshstack_integration.tf +++ b/modules/ske/forgejo-connector/meshstack_integration.tf @@ -99,7 +99,6 @@ module "backplane" { cluster_ca_certificate = var.cluster_ca_certificate client_key = var.client_key client_certificate = var.client_certificate - cluster_kubeconfig = var.cluster_kubeconfig } resource "meshstack_building_block_definition" "this" { @@ -184,20 +183,25 @@ resource "meshstack_building_block_definition" "this" { argument = jsonencode(var.harbor_host) } - cluster_host = { - display_name = "cluster_host" - description = "Kubernetes API server URL used for generated kubeconfig." - type = "STRING" + kubeconfig = { + display_name = "kubeconfig" + description = "Static cluster kubeconfig content merged with generated service-account credentials." + type = "CODE" assignment_type = "STATIC" - argument = jsonencode(var.cluster_host) + sensitive = { + argument = { + secret_value = jsonencode(yamldecode(var.cluster_kubeconfig)) + secret_version = sha256(var.cluster_kubeconfig) + } + } } - cluster_ca_certificate = { - display_name = "cluster_ca_certificate" - description = "Base64-encoded Kubernetes cluster CA certificate used for generated kubeconfig." + kubeconfig_cluster_name = { + display_name = "kubeconfig_cluster_name" + description = "Cluster name used to connect static kubeconfig and generated user/context entries." type = "STRING" assignment_type = "STATIC" - argument = jsonencode(var.cluster_ca_certificate) + argument = jsonencode(module.backplane.kubeconfig_cluster_name) } harbor_username = {