Skip to content

feat(ref-arch)!: order forms of the STACKIT Landing Zone and Kubernetes Platform - #425

Draft
grubmeshi wants to merge 9 commits into
feature/ske-ref-arch-migrationfrom
feature/ske-ref-arch-migration-lz-form
Draft

grubmeshi wants to merge 9 commits into
feature/ske-ref-arch-migrationfrom
feature/ske-ref-arch-migration-lz-form

Conversation

@grubmeshi

@grubmeshi grubmeshi commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #424: the base is feature/ske-ref-arch-migration. Draft until #424 merges. It also carries the STACKIT Kubernetes Platform changes that were #426.

The order forms of the STACKIT Landing Zone and the STACKIT Kubernetes Platform reference architectures follow one set of rules, which the scorecard now reports.

Commits (reading order)

  1. 9ab32a9f feat(scorecard): the input default and order rules, in the instructions and the scorecard.
  2. 4b713c8a chore(ref-arch/otc-landingzone): drops a stale description length note.
  3. 37d83657 refactor: refs without kind in the starterkit modules, the SKE landingzone input, the nested platform and the LZ summary. Mechanical.
  4. 7805cca4 feat(stackit/stackit-project-starterkit)! and 5. bf3c6903 feat(ske/ske-starterkit)!: the PAYMENT_METHOD input of the two starterkits.
  5. 1e9c89a3 feat(ref-arch/stackit-landingzone)!: the LZ order form.
  6. 7d751302 feat(ref-arch/stackit-landingzone): the project-creation service account name pin.
  7. 4108a526 feat(ref-arch/stackit-kubernetes): the nested platform without an AI model.
  8. bcd02413 feat(ref-arch/stackit-kubernetes)!: the SKE order form, outer and nested definition. The largest commit; meshstack_integration.tf and buildingblock/variables.tf read best as new files in display order.

Input defaults and order (docs and scorecard)

  • A buildingblock variable fed by a required input has no default and is nullable = false; an input with a sane default carries it in default_value. meshStack currently sends no value for an input whose value is null, optional or hidden by a condition, so the variable of an optional or conditional input has default = null, and the code checks only for null.
  • Inputs and the variables they feed are declared in display order. Inputs meshStack fills in follow the user inputs, and hub comes last.
  • Scorecard (report-only): bbd_input_order reports inputs or variables out of order. bbd_input_defaults replaces bbd_optional_over_default and reports variables of required inputs that have a default or are nullable, and "" handled as unset. The default = null of optional and conditional variables is in the instructions only.

STACKIT Landing Zone

  • Input order: platform identifier, playground mode, use global location, organization, root folder name, deployment service account key, owner email, topology, network, role mapping, tags, starterkit approval policies, imports, then workspace and hub.
  • use_global_location defaults to true. root_folder_name, imports and network are optional or conditional and keep default = null.
  • Playground mode is an order form input, off by default. A terraform_data pin fails a run that changes it after the order. Deletion still works.
  • Starterkit Approval Policies is a JSON order form input, all gates off by default, hidden in playground mode, where the buildingblock sets no gates.
  • Role mapping is an object of admin, user, reader and organization_onboarding (default true, so an existing block keeps onboarding users).
  • Tags have no defaults; the default_tags variable is gone. project_owner_tag_key is optional, and null sets no owner tag.
  • Imports: schema titles are the keys; imports.platform = {} is now imports.adopt_platform = true.
  • Project-creation service account name pin: the first run stores the name in a terraform_data (ignore_changes = [input]): the adopted imports.project_definition.service_account_name, else the name derived from the platform identifier. Every later run reads it from there, so imports can go back to null after the adoption without renaming, and so replacing, the account that owns every tenant project. The code reads the pin's input, because its output is unknown at the first plan and would replace the account.
  • The summary's paste block for the Kubernetes platform hands out platform_ref and landingzone_refs without kind.
  • Descriptions call the supplied account the deployment service account and the created one the project-creation service account.

STACKIT Kubernetes Platform

  • Inputs and variables of the outer and the nested definition are in display order. The order follows the playground draft tuned in meshPanel.
  • Playground mode and Starterkit Random Name Suffix (starterkit_add_random_name_suffix, default true, not updateable) are order form inputs, right after each other. A terraform_data pin fails a run that changes either after the order: a changed suffix renames, and so replaces, every project and tenant the starterkit created.
  • Approval Policies and Starterkit Approval Policies are JSON order form inputs. The approval_policies variable sets only the gates of this definition.
  • Tags and stages are JSON inputs built from {key, values} lists. The buildingblock folds them back into maps, so the nested building block gets the same values as before.
  • Quota definitions and imports are JSON with schemas whose titles are the keys. imports.ske = {} and imports.ingress = {} are now imports.adopt_ske and imports.adopt_ingress. Imports, Import Secrets, Starterkit Random Name Suffix, DNS Domain and both approval policies are hidden in playground mode; there the buildingblock always suffixes the starterkit projects, uses <platform identifier>.stackit.run and sets no gates, and the suffix guard compares that effective value.
  • Order: platform identifier, Phase 2 Completed, Use Global Location (default now true), payment method, Playground Mode (default now true), landing zone, landing zone variant, starterkit random name suffix, Starter Kit Demo, DNS Domain, stages, Quota Definitions (right after stages; a stage's quotas entry names a quota_key from it), tags, Overrides, approval policies, starterkit approval policies, imports, import secrets, then the generated inputs and hub.
  • Overrides (optional JSON, updateable_by_consumer) replaces cluster_name, cluster_issuer_email and project_identifier: {cluster_name, cluster_issuer_email, project_identifier}, each optional with a pattern, additionalProperties = false. Left out: a generated cluster name, the platform's service account as ACME contact, <platform identifier>-ske.
  • Starter Kit Demo (required JSON, updateable_by_consumer) replaces starterkit_app_name, starterkit_repo_clone_addr and ai_model: {name, template_repo, ai_model}, default ai-summarizer from the likvid-bank template on openai/gpt-oss-120b. Without ai_model the nested run orders no AI Model Serving block, its federation leaves out that definition and the Forgejo connector creates no stackit-ai secret. With an AI model all of these stay as they were, the connector's secrets_revision included.
  • DNS Domain (required STRING, default stackit.run, updateable_by_consumer) replaces dns_parent_domain and dns_subdomain. Only the free STACKIT domains are accepted (stackit.run|zone|rocks|gg, runs.onstackit.cloud): a bare one gives <platform identifier>.<domain>, one label of at most 20 characters more is the zone itself (likvid.stackit.run). The nested building block gets the same dns_subdomain and dns_parent_domain as before.
  • project_owner_tag_key is optional; only null means unset. Form descriptions say "leave out" for values the code checks only for null.
  • The JSON inputs with a default (Starter Kit Demo, Stages, Tags, both approval policies) carry it in default_value and in the schema's default, both from one local, because the meshPanel order form shows only schema defaults.
  • The optional and conditional inputs (starterkit_add_random_name_suffix, dns_domain, approval_policies, starterkit_approval_policies, overrides, quota_definitions, imports, import_secrets) keep default = null; the four conditional ones with a form default are required by a validation outside playground mode.
  • The nested definition's imports input is updateable_by_consumer, so the outer run can send the new adopt_ske and adopt_ingress keys to an existing nested block.
  • platform_engineer_role_mapping is removed from both definitions. No foundation set it, and the Git, container registry and Secrets Manager module defaults give Project Admins the same roles as before: Forgejo owner, container-registry.artifactory.admin, secrets-manager.reader.
  • Landing zone refs without kind: the landingzone input takes platform_ref = { uuid } and landingzone_refs = { <variant> = { name } }. The refs reach only the tenant's platform_ref and landing_zone_ref, where the provider makes kind optional with a default (internal/provider/schema_utils.go:152-218, used by tenant_resource.go:373-388, since provider v0.26.0; this module requires >= 0.27.0). A value that still has kind is accepted, because the extra attribute is dropped. The same holds for the platform_ref and landing_zone_refs variables of SKE Starterkit and STACKIT Project Starterkit and the nested platform's automation_identity.building_block_ref (a parent ref): they take only uuid or name. target_ref keeps kind, which the provider requires to tell a tenant from a workspace, and payment_method keeps it as part of the value meshStack hands the run.

Payment methods

meshStack's PAYMENT_METHOD input lets whoever orders a building block pick one of the ordering workspace's payment methods (provider >= v0.26.5). The run receives {"kind": "meshPaymentMethod", "name": "<identifier>"}. Such an input is CODE, has no default, and is updateable_by_consumer because meshStack requires that of one a new version adds.

  • STACKIT Kubernetes Platform: the required payment_method (display order 20, after Use Global Location) replaces the optional payment_method_identifier and sets the payment method of the platform's own meshProject.
  • SKE Starterkit and STACKIT Project Starterkit: a new required payment_method sets the payment method of every meshProject they create. Until now these projects got none, unless the workspace had an active payment method named default.
  • The two stay apart: the platform's project uses the platform team's workspace, the starterkit projects the application team's workspace. Nothing passes a payment method from the platform to the starterkit.
  • The ref arch and the SKE Starterkit e2e create a payment method in the test workspace and order with it.
  • Scorecard: bbd_input_order counts a PAYMENT_METHOD input as one a person sets.

Breaking changes for callers

  • LZ: send playground_mode and starterkit_approval_policies as building block inputs; send imports.adopt_platform = true; set role_mapping.organization_onboarding (the stackit_organization_onboarding_enabled input is gone). The module variables playground_mode, starterkit_approval_policies and default_tags are gone.
  • SKE: send playground_mode, starterkit_add_random_name_suffix, approval_policies and starterkit_approval_policies as building block inputs; tags and stages as lists; imports.adopt_ske and imports.adopt_ingress; null for an unset project_owner_tag_key. The module variables playground_mode, starterkit_add_random_name_suffix, starterkit_approval_policies and platform_engineer_role_mapping are gone. Keep starterkit_add_random_name_suffix as the adopted starterkit had it.
  • SKE: send overrides = {cluster_name, cluster_issuer_email, project_identifier}, starterkit_demo = {name, template_repo, ai_model} and dns_domain instead of the eight inputs they replace. dns_domain is <dns_subdomain>.<dns_parent_domain>, or just the parent domain when the subdomain is the platform identifier. A caller that relied on playground_mode = false sets it explicitly. A caller that relied on use_global_location = false without imports.kubernetes_platform.location_name sets it explicitly.
  • SKE: send payment_method = { value = jsonencode({ kind = "meshPaymentMethod", name = "<identifier>" }) } (or jsonencode(meshstack_payment_method.x.ref)) instead of payment_method_identifier; the payment method must belong to the ordering workspace.
  • SKE Starterkit and STACKIT Project Starterkit: an existing starterkit building block waits for user input after the upgrade, until someone in its workspace picks a payment method.

Verified

  • tofu validate passes in the changed directories. Scorecard: bbd_input_order and bbd_input_defaults pass for both architectures; no regression from the overrides, starter kit demo and DNS domain change.
  • DNS domain split, checked with tofu: stackit.run gives <platform identifier>.stackit.run, likvid.stackit.run and meshcloud-dev.stackit.run keep their label; a.b.stackit.run, example.com and a label starting with a dash are refused.
  • Service account pin, with local state: a first run with the adopted name pins mesh-project and the name is known at plan; a later run with imports = null or another name plans no change; a fresh install pins the derived name.
  • Kind-less refs: a plan that imports ICF's live tenant through the tenant module, with refs without kind and with kind, shows 1 to import, 0 to change, 0 to destroy in both cases.
  • Callers pinned to this branch: ICF landing zone and SKE platform plan 0 to add, 2 to change, 0 to destroy (definition and building block). LCF landing zone plans 0 to add, 5 to change, 0 to destroy (the extra changes are the control tower definitions, whose platform_ref is known only after the landing zone block's run), LCF SKE 0 to add, 2 to change, 0 to destroy. TCF sandbox landing zone plans 0 to add, 3 to change, 0 to destroy; TCF SKE plans the first creation.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Scorecard Check

Scorecard run on commit cf62ccdb66c48f296381c55ee4dc521f62caa5b0 relative to origin/feature/ske-ref-arch-migration

📊 meshstack-hub Module Scorecard

Generated: 2026-11-04 | Modules scanned: 2 | Categories: 8

📋 Per-Module Category Summary

Score per category per module. n/a = category does not apply to this module.

Module Overall Core Structure Integration AWS Backplane Azure Backplane GCP Backplane STACKIT Backplane Shared Practices Testing
ske/ske-starterkit 🟢 94% 🟢 100% 🟢 100% n/a n/a n/a n/a 🟡 67% 🟢 80%
stackit/stackit-project-starterkit 🟢 93% 🟢 100% 🟢 100% n/a n/a n/a n/a 🟢 100% 🔴 33%

⚠️ 2 modules have failing checks — failing categories are expanded below.

Core Structure — ✅ all passing

Basic module file structure and documentation — applies to 2 modules

Module Score 📦 🔗 📋 📝 🖼️ 📌 🚦 🩹 🧼 ❄️ 🔒
ske/ske-starterkit 🟢 100% ✅ ✅ ➖ ✅ ✅ ✅ ✅ ✅ ✅ ➖ ✅
stackit/stackit-project-starterkit 🟢 100% ✅ ✅ ➖ ✅ ✅ ✅ ✅ ✅ ➖ ➖ ✅

Core Structure — Summary

Emoji Criterion Coverage Status
📦 buildingblock/ directory exists 2/2 🟢 100%
🔗 meshstack_integration.tf present 2/2 🟢 100%
📋 buildingblock/APP_TEAM_README.md present (no-integration fallback) n/a —
📝 buildingblock/README.md with YAML front-matter 2/2 🟢 100%
🖼️ buildingblock/logo.png or logo.svg included 2/2 🟢 100%
📌 buildingblock/versions.tf present 2/2 🟢 100%
🚦 Child meshstack_building_block asserts a SUCCEEDED run 2/2 🟢 100%
🩹 Every try() carries a comment saying why 2/2 🟢 100%
🧼 Pre-run scripts install no tools on the runner 1/1 🟢 100%
❄️ A module flake sits in nix/, is pinned, and Terraform calls it n/a —
🔒 Provider versions float within one major (>= X.Y.Z, < N.0.0) 2/2 🟢 100%
Integration — ✅ all passing

meshstack_integration.tf conventions — applies to 2 modules

Module Score 🏷️ 🏢 📤 🔌 📎 🔀 🌱 📋 🏷️ 🧱 🏪 📖 📝 📊 🚫 🔄 🪪
ske/ske-starterkit 🟢 100% ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ➖ ➖
stackit/stackit-project-starterkit 🟢 100% ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ➖ ➖

Integration — Summary

Emoji Criterion Coverage Status
🏷️ variable "hub" in integration 2/2 🟢 100%
🏢 variable "meshstack" in integration 2/2 🟢 100%
📤 building_block_definition output exposed 2/2 🟢 100%
🔌 meshcloud/meshstack in required_providers 2/2 🟢 100%
📎 backplane source uses var.hub.git_ref 2/2 🟢 100%
🔀 ref_name uses var.hub.git_ref 2/2 🟢 100%
🌱 BBD terraform_version >= 1.12.0 2/2 🟢 100%
📋 version_spec.draft uses var.hub.bbd_draft 2/2 🟢 100%
🏷️ BBD metadata.tags forwards var.meshstack.tags 2/2 🟢 100%
🧱 BBD input argument vars with optional() have explicit defaults 2/2 🟢 100%
🏪 BBD catalog properties are overridable 2/2 🟢 100%
📖 BBD readme field present 2/2 🟢 100%
📝 BBD readme starts with plain-text description (no heading) 2/2 🟢 100%
📊 BBD readme has shared responsibility table (✅/❌) 2/2 🟢 100%
🚫 No documentation_md output in backplane 2/2 🟢 100%
🔄 meshstack_platform has lifecycle ignore_changes = [availability] n/a —
🪪 Trusts the runner's identity, not the replicator's n/a —
AWS Backplane — not applicable

AWS automation principal conventions (WIF or cross-account StackSet) — applies to 0 modules

No applicable modules.

Azure Backplane — not applicable

Azure UAMI-based automation principal conventions — applies to 0 modules

No applicable modules.

GCP Backplane — not applicable

GCP workload-identity-federation automation principal conventions — applies to 0 modules

No applicable modules.

STACKIT Backplane — not applicable

STACKIT WIF-based automation principal conventions — applies to 0 modules

No applicable modules.

Shared Practices — some checks failing

Practices modules and reference architectures share — applies to 2 modules

Module Score 🎯 🔐 🫥 🧾 🔢 🪞
ske/ske-starterkit 🟡 67% ✅ ✅ ➖ ➖ ➖ ❌
stackit/stackit-project-starterkit 🟢 100% ✅ ✅ ➖ ➖ ➖ ➖

Shared Practices — Summary

Emoji Criterion Coverage Status
🎯 meshStack *_ref attributes take a ref, never an object built from a uuid 2/2 🟢 100%
🔐 no building block output carries a secret 2/2 🟢 100%
🫥 Sensitive building block variables are ephemeral n/a —
🧾 User-facing BBD inputs backed by an object or map variable are JSON with a json_schema n/a —
🔢 BBD inputs and their variables are declared in display order n/a —
🪞 The definition owns input defaults: variables fed by required inputs have no default and are not nullable, no "" as unset 0/1 🔴 0%
Testing — some checks failing

End-to-end test coverage — applies to 2 modules

Module Score ⚙️ 🧪 🚫 🎭 ✅
ske/ske-starterkit 🟢 80% ❌ ✅ ✅ ✅ ✅
stackit/stackit-project-starterkit 🔴 33% ➖ ❌ ✅ ➖ ❌

Testing — Summary

Emoji Criterion Coverage Status
⚙️ backplane/ directory (optional tier) 0/1 🔴 0%
🧪 e2e/ test directory exists 1/2 🟡 50%
🚫 no .tftest.hcl outside e2e/ 2/2 🟢 100%
🎭 every .tftest.hcl runs against real infrastructure 1/1 🟢 100%
✅ e2e/ contains .tftest.hcl files 1/2 🟡 50%

📈 Overall Summary

Overall Average Score: 94%

Score Distribution

  • 🟢 High maturity (≥80%): 2 modules
  • 🟡 Medium maturity (50–79%): 0 modules
  • 🔴 Low maturity (<50%): 0 modules

📊 meshstack-hub Reference Architecture Scorecard

Generated: 2026-11-04 | Reference Architectures scanned: 3 | Categories: 3

📋 Per-Reference Architecture Category Summary

Score per category per reference architecture. n/a = category does not apply to this reference architecture.
Included modules are scored by the module scorecard, and only summarized here.

Reference Architecture Overall Shared Practices Reference Architecture Testing Included modules
otc-landingzone 🔴 45% 🔴 20% 🟡 75% 🟡 50% 6 modules; 6 with failures: otc/cce 83%, otc/federation-mapping 85%, otc/network 86%, otc/obs-bucket 83%, otc/project 86%, otc/rds 83%; not scored: modules/otc
stackit-kubernetes 🟡 77% 🟡 50% 🟢 100% 🟢 100% 12 modules; 12 with failures: kubernetes/ingress 83%, ske/cluster 79%, ske/forgejo-connector 89%, ske/ske-starterkit 94%, stackit/ai-llm 83%, stackit/container-registry 80%, stackit/dns 82%, stackit/git 77%, stackit/git-repository 93%, stackit/secrets-manager 92%, stackit/service-account 97%, stackit/service-account-federation 97%; not scored: modules/kubernetes
stackit-landingzone 🟡 75% 🟢 83% 🟡 75% 🟡 50% 6 modules; 6 with failures: stackit/network 97%, stackit/network-area 94%, stackit/project 83%, stackit/service-account 97%, stackit/service-account-federation 97%, stackit/stackit-project-starterkit 93%; not scored: modules/stackit

⚠️ 3 reference architectures have failing checks — failing categories are expanded below.

Shared Practices — some checks failing

Practices modules and reference architectures share — applies to 3 reference architectures

Reference Architecture Score 🎯 🔐 🫥 🧾 🔢 🪞
otc-landingzone 🔴 20% ❌ ✅ ❌ ➖ ❌ ❌
stackit-kubernetes 🟡 50% ❌ ✅ ❌ ❌ ✅ ✅
stackit-landingzone 🟢 83% ❌ ✅ ✅ ✅ ✅ ✅

Shared Practices — Summary

Emoji Criterion Coverage Status
🎯 meshStack *_ref attributes take a ref, never an object built from a uuid 0/3 🔴 0%
🔐 no building block output carries a secret 3/3 🟢 100%
🫥 Sensitive building block variables are ephemeral 1/3 🔴 33%
🧾 User-facing BBD inputs backed by an object or map variable are JSON with a json_schema 1/2 🟡 50%
🔢 BBD inputs and their variables are declared in display order 2/3 🟡 67%
🪞 The definition owns input defaults: variables fed by required inputs have no default and are not nullable, no "" as unset 2/3 🟡 67%
Reference Architecture — some checks failing

How a reference architecture orders and documents its building blocks — applies to 3 reference architectures

Reference Architecture Score 🆕 📌 🛂 🗺️
otc-landingzone 🟡 75% ❌ ✅ ✅ ✅
stackit-kubernetes 🟢 100% ✅ ✅ ✅ ✅
stackit-landingzone 🟡 75% ❌ ✅ ✅ ✅

Reference Architecture — Summary

Emoji Criterion Coverage Status
🆕 Children are ordered with, and outputs hand out, version_latest 1/3 🔴 33%
📌 Hub sources, ref_name and assets follow var.hub.git_ref 3/3 🟢 100%
🛂 The definition takes its approval policies from a variable 3/3 🟢 100%
🗺️ README.md shows a committed diagram (.dot + .svg) 3/3 🟢 100%
Testing — some checks failing

End-to-end test coverage — applies to 3 reference architectures

Reference Architecture Score 🚫 🎭 🧪
otc-landingzone 🟡 50% ✅ ➖ ❌
stackit-kubernetes 🟢 100% ✅ ✅ ✅
stackit-landingzone 🟡 50% ✅ ➖ ❌

Testing — Summary

Emoji Criterion Coverage Status
🚫 no .tftest.hcl outside e2e/ 3/3 🟢 100%
🎭 every .tftest.hcl runs against real infrastructure 1/1 🟢 100%
🧪 e2e/main.tf with a .tftest.hcl 1/3 🔴 33%

📈 Overall Summary

Overall Average Score: 66%

Score Distribution

  • 🟢 High maturity (≥80%): 0 reference architectures
  • 🟡 Medium maturity (50–79%): 2 reference architectures
  • 🔴 Low maturity (<50%): 1 reference architectures

@grubmeshi
grubmeshi force-pushed the feature/ske-ref-arch-migration branch from d0317b2 to 2f3bb67 Compare November 4, 2026 12:34
@grubmeshi
grubmeshi force-pushed the feature/ske-ref-arch-migration-lz-form branch from 0ea12de to 1dd5b26 Compare November 4, 2026 12:37
@grubmeshi
grubmeshi force-pushed the feature/ske-ref-arch-migration-lz-form branch from 5944d3b to 554c2b5 Compare November 4, 2026 13:20
@grubmeshi grubmeshi changed the title feat(ref-arch/stackit-landingzone)!: align the order form with the tuned playground draft feat(ref-arch)!: order forms of the STACKIT Landing Zone and Kubernetes Platform Nov 4, 2026
@grubmeshi
grubmeshi force-pushed the feature/ske-ref-arch-migration-lz-form branch 3 times, most recently from bc3d260 to d52da0a Compare November 4, 2026 13:57
grubmeshi and others added 5 commits November 4, 2026 22:43
The runner writes an empty input as null, so a variable default never applies. A buildingblock
variable fed by a required input has no default and is nullable = false; an input with a sane
default carries it in default_value, a JSON object input also in its schema, because the order
form shows only those. An optional input is nullable and checked only for null. Inputs and the
variables they feed are declared in display order; inputs meshStack fills in follow those a person
sets (USER_INPUT, PAYMENT_METHOD, PLATFORM_OPERATOR_MANUAL_INPUT, STATIC), and hub comes last.

bbd_input_order and bbd_input_defaults report both rules; bbd_input_defaults replaces
bbd_optional_over_default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The STACKIT Kubernetes Platform definition on meshstack-dev carries input descriptions of up to
260 characters, so the 200 character limit the note names does not hold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The provider defaults kind on a tenant's platform_ref and landing_zone_ref and on
parent_building_block_refs, so the ske-starterkit and stackit-project-starterkit variables, the
nested platform's automation identity and the STACKIT Kubernetes Platform's landingzone input take
only the uuid or name. A value that still carries kind is accepted, because the extra attribute is
dropped. The STACKIT Landing Zone summary hands out the refs without kind. target_ref keeps kind,
which the provider requires to tell a tenant from a workspace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the created project

The application team picks one of its workspace's payment methods on order.

BREAKING CHANGE: the definition gains the required input payment_method; existing building blocks
wait for that pick after the upgrade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…'s projects

The application team picks one of its workspace's payment methods on order. The e2e creates a
payment method of its own for it.

BREAKING CHANGE: the definition gains the required input payment_method; existing building blocks
wait for that pick after the upgrade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@grubmeshi
grubmeshi force-pushed the feature/ske-ref-arch-migration-lz-form branch from 83d2500 to d5ea0cb Compare November 4, 2026 21:46
grubmeshi and others added 4 commits November 4, 2026 22:48
- Inputs and buildingblock variables follow the setup steps in display order; generated inputs
  follow the user inputs and hub comes last.
- The definition owns input defaults: root_folder_name, network and imports lose their variable
  default; use_global_location defaults to true.
- playground_mode is an order form input, off by default, and a terraform_data pin fails a run
  that changes it after the order; deletion still works.
- Starterkit Approval Policies is a JSON order form input with all gates off by default, its
  schema carrying the defaults the form shows. Playground mode hides it and gates nothing.
- role_mapping is an object of admin, user and reader with organization_onboarding, which
  defaults to true, so an existing building block keeps onboarding users.
- tags carry no defaults; project_owner_tag_key is optional, here and in
  stackit-project-starterkit, and null sets no owner tag.
- imports titles are the keys; imports.platform becomes the boolean imports.adopt_platform.
- The docs call the two accounts the deployment and the project-creation service account.

BREAKING CHANGE: callers send playground_mode and, outside playground mode,
starterkit_approval_policies as building block inputs. imports.platform = {} is now
imports.adopt_platform = true, and the input stackit_organization_onboarding_enabled is now
role_mapping.organization_onboarding. The module variables playground_mode,
starterkit_approval_policies and default_tags are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…account name

The first run stores the name, so imports can go back to null without replacing the service
account that owns every tenant project.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…AI model

The nested definition's ai_model input is optional. Without it the run orders no AI Model Serving
block, the federation does not trust its definition, and the Forgejo connector creates no
stackit-ai secret. With an AI model every input and the connector's secrets revision stay as
they were.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The order form asks, in this order: platform identifier, Phase 2 Completed, Use Global Location
(on by default), payment method, Playground Mode (on by default, so a form left as is builds a
throwaway platform), the landing zone and its variant, then the starter kit, DNS, stages, quota
definitions, tags, overrides, approval policies and imports. Generated inputs and then hub come
last, in the outer and in the nested definition, and the buildingblock variables follow the same
order.

- The definition owns input defaults: fed variables have no default, optional inputs are nullable
  and only null means unset. JSON inputs carry their defaults in default_value and in the schema,
  because the order form shows only the latter; both come from one local.
- payment_method picks the platform project's payment method from the ordering workspace.
- playground_mode and starterkit_add_random_name_suffix are order form inputs. A terraform_data pin
  fails a run that changes either after the order, because a changed suffix renames, and so
  replaces, every project and tenant the starterkit created.
- Playground mode hides and fixes the starterkit suffix (on), the DNS domain (stackit.run), both
  approval policies (no gates), Imports and Import Secrets.
- approval_policies and starterkit_approval_policies are JSON order form inputs for the registered
  definitions; the approval_policies variable keeps the gates of this definition.
- tags and stages are JSON inputs built from {key, values} lists, stages a list of named stages;
  quota_definitions and imports are JSON with schemas whose titles are the keys.
- overrides = {cluster_name, cluster_issuer_email, project_identifier}, each field optional with a
  pattern, replaces the three inputs.
- starterkit_demo = {name, template_repo, ai_model} replaces starterkit_app_name,
  starterkit_repo_clone_addr and ai_model. Without ai_model the platform sets up no Model Serving
  token and no stackit-ai secret.
- dns_domain replaces dns_parent_domain and dns_subdomain. It accepts only the free STACKIT
  domains: a bare one gives the zone <platform identifier>.<domain>, one label of at most 20
  characters more is the zone itself.
- imports.ske = {} and imports.ingress = {} become imports.adopt_ske and imports.adopt_ingress.
- project_owner_tag_key is optional; null sets no owner tag.
- platform_engineer_role_mapping is gone; the Git, registry and Secrets Manager module defaults
  grant Project Admins the same roles as before.

BREAKING CHANGE: callers send playground_mode, payment_method, starterkit_demo and, outside
playground mode, starterkit_add_random_name_suffix, dns_domain, approval_policies and
starterkit_approval_policies as building block inputs; tags and stages as lists; overrides in place
of cluster_name, cluster_issuer_email and project_identifier; imports.adopt_ske and
imports.adopt_ingress; and null for an unset project_owner_tag_key. payment_method_identifier,
starterkit_app_name, starterkit_repo_clone_addr, ai_model, dns_parent_domain and dns_subdomain are
gone. A caller that relied on playground_mode defaulting to false, or on use_global_location =
false without imports.kubernetes_platform.location_name, sets it explicitly. The module variables
playground_mode, starterkit_add_random_name_suffix, starterkit_approval_policies and
platform_engineer_role_mapping are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@grubmeshi
grubmeshi force-pushed the feature/ske-ref-arch-migration-lz-form branch from d5ea0cb to bcd0241 Compare November 4, 2026 21:49
@sonarqubecloud

sonarqubecloud Bot commented Nov 4, 2026

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant