Repository navigation
Conversation
Scorecard Check
📊 meshstack-hub Module Scorecard
📋 Per-Module Category SummaryScore per category per module.
Core Structure — ✅ all passingBasic module file structure and documentation — applies to 2 modules
Core Structure — Summary
Integration — ✅ all passingmeshstack_integration.tf conventions — applies to 2 modules
Integration — Summary
AWS Backplane — not applicableAWS automation principal conventions (WIF or cross-account StackSet) — applies to 0 modules No applicable modules. Azure Backplane — not applicableAzure UAMI-based automation principal conventions — applies to 0 modules No applicable modules. GCP Backplane — not applicableGCP workload-identity-federation automation principal conventions — applies to 0 modules No applicable modules. STACKIT Backplane — not applicableSTACKIT WIF-based automation principal conventions — applies to 0 modules No applicable modules. Shared Practices — some checks failingPractices modules and reference architectures share — applies to 2 modules
Shared Practices — Summary
Testing — some checks failingEnd-to-end test coverage — applies to 2 modules
Testing — Summary
📈 Overall SummaryOverall Average Score: 94%Score Distribution
📊 meshstack-hub Reference Architecture Scorecard
📋 Per-Reference Architecture Category SummaryScore per category per reference architecture.
Shared Practices — some checks failingPractices modules and reference architectures share — applies to 3 reference architectures
Shared Practices — Summary
Reference Architecture — some checks failingHow a reference architecture orders and documents its building blocks — applies to 3 reference architectures
Reference Architecture — Summary
Testing — some checks failingEnd-to-end test coverage — applies to 3 reference architectures
Testing — Summary
📈 Overall SummaryOverall Average Score: 66%Score Distribution
|
d0317b2 to
2f3bb67
Compare
0ea12de to
1dd5b26
Compare
5944d3b to
554c2b5
Compare
bc3d260 to
d52da0a
Compare
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>
83d2500 to
d5ea0cb
Compare
- 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>
d5ea0cb to
bcd0241
Compare
|



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)
9ab32a9ffeat(scorecard): the input default and order rules, in the instructions and the scorecard.4b713c8achore(ref-arch/otc-landingzone): drops a stale description length note.37d83657refactor: refs withoutkindin the starterkit modules, the SKE landingzone input, the nested platform and the LZ summary. Mechanical.7805cca4feat(stackit/stackit-project-starterkit)!and 5.bf3c6903feat(ske/ske-starterkit)!: thePAYMENT_METHODinput of the two starterkits.1e9c89a3feat(ref-arch/stackit-landingzone)!: the LZ order form.7d751302feat(ref-arch/stackit-landingzone): the project-creation service account name pin.4108a526feat(ref-arch/stackit-kubernetes): the nested platform without an AI model.bcd02413feat(ref-arch/stackit-kubernetes)!: the SKE order form, outer and nested definition. The largest commit;meshstack_integration.tfandbuildingblock/variables.tfread best as new files in display order.Input defaults and order (docs and scorecard)
nullable = false; an input with a sane default carries it indefault_value. meshStack currently sends no value for an input whose value is null, optional or hidden by acondition, so the variable of an optional or conditional input hasdefault = null, and the code checks only for null.hubcomes last.bbd_input_orderreports inputs or variables out of order.bbd_input_defaultsreplacesbbd_optional_over_defaultand reports variables of required inputs that have a default or are nullable, and""handled as unset. Thedefault = nullof optional and conditional variables is in the instructions only.STACKIT Landing Zone
hub.use_global_locationdefaults totrue.root_folder_name,importsandnetworkare optional or conditional and keepdefault = null.terraform_datapin fails a run that changes it after the order. Deletion still works.admin,user,readerandorganization_onboarding(defaulttrue, so an existing block keeps onboarding users).default_tagsvariable is gone.project_owner_tag_keyis optional, and null sets no owner tag.imports.platform = {}is nowimports.adopt_platform = true.terraform_data(ignore_changes = [input]): the adoptedimports.project_definition.service_account_name, else the name derived from the platform identifier. Every later run reads it from there, soimportscan go back to null after the adoption without renaming, and so replacing, the account that owns every tenant project. The code reads the pin'sinput, because itsoutputis unknown at the first plan and would replace the account.platform_refandlandingzone_refswithoutkind.STACKIT Kubernetes Platform
starterkit_add_random_name_suffix, defaulttrue, not updateable) are order form inputs, right after each other. Aterraform_datapin fails a run that changes either after the order: a changed suffix renames, and so replaces, every project and tenant the starterkit created.approval_policiesvariable sets only the gates of this definition.{key, values}lists. The buildingblock folds them back into maps, so the nested building block gets the same values as before.imports.ske = {}andimports.ingress = {}are nowimports.adopt_skeandimports.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.runand sets no gates, and the suffix guard compares that effective value.true), payment method, Playground Mode (default nowtrue), landing zone, landing zone variant, starterkit random name suffix, Starter Kit Demo, DNS Domain, stages, Quota Definitions (right after stages; a stage'squotasentry names aquota_keyfrom it), tags, Overrides, approval policies, starterkit approval policies, imports, import secrets, then the generated inputs andhub.updateable_by_consumer) replacescluster_name,cluster_issuer_emailandproject_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.updateable_by_consumer) replacesstarterkit_app_name,starterkit_repo_clone_addrandai_model:{name, template_repo, ai_model}, defaultai-summarizerfrom the likvid-bank template onopenai/gpt-oss-120b. Withoutai_modelthe nested run orders no AI Model Serving block, its federation leaves out that definition and the Forgejo connector creates nostackit-aisecret. With an AI model all of these stay as they were, the connector'ssecrets_revisionincluded.stackit.run,updateable_by_consumer) replacesdns_parent_domainanddns_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 samedns_subdomainanddns_parent_domainas before.project_owner_tag_keyis optional; only null means unset. Form descriptions say "leave out" for values the code checks only for null.default_valueand in the schema'sdefault, both from one local, because the meshPanel order form shows only schema defaults.starterkit_add_random_name_suffix,dns_domain,approval_policies,starterkit_approval_policies,overrides,quota_definitions,imports,import_secrets) keepdefault = null; the four conditional ones with a form default are required by a validation outside playground mode.importsinput isupdateable_by_consumer, so the outer run can send the newadopt_skeandadopt_ingresskeys to an existing nested block.platform_engineer_role_mappingis 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: Forgejoowner,container-registry.artifactory.admin,secrets-manager.reader.kind: thelandingzoneinput takesplatform_ref = { uuid }andlandingzone_refs = { <variant> = { name } }. The refs reach only the tenant'splatform_refandlanding_zone_ref, where the provider makeskindoptional with a default (internal/provider/schema_utils.go:152-218, used bytenant_resource.go:373-388, since provider v0.26.0; this module requires >= 0.27.0). A value that still haskindis accepted, because the extra attribute is dropped. The same holds for theplatform_refandlanding_zone_refsvariables of SKE Starterkit and STACKIT Project Starterkit and the nested platform'sautomation_identity.building_block_ref(a parent ref): they take onlyuuidorname.target_refkeepskind, which the provider requires to tell a tenant from a workspace, andpayment_methodkeeps it as part of the value meshStack hands the run.Payment methods
meshStack's
PAYMENT_METHODinput 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 isCODE, has no default, and isupdateable_by_consumerbecause meshStack requires that of one a new version adds.payment_method(display order 20, after Use Global Location) replaces the optionalpayment_method_identifierand sets the payment method of the platform's own meshProject.payment_methodsets the payment method of every meshProject they create. Until now these projects got none, unless the workspace had an active payment method nameddefault.bbd_input_ordercounts aPAYMENT_METHODinput as one a person sets.Breaking changes for callers
playground_modeandstarterkit_approval_policiesas building block inputs; sendimports.adopt_platform = true; setrole_mapping.organization_onboarding(thestackit_organization_onboarding_enabledinput is gone). The module variablesplayground_mode,starterkit_approval_policiesanddefault_tagsare gone.playground_mode,starterkit_add_random_name_suffix,approval_policiesandstarterkit_approval_policiesas building block inputs; tags and stages as lists;imports.adopt_skeandimports.adopt_ingress; null for an unsetproject_owner_tag_key. The module variablesplayground_mode,starterkit_add_random_name_suffix,starterkit_approval_policiesandplatform_engineer_role_mappingare gone. Keepstarterkit_add_random_name_suffixas the adopted starterkit had it.overrides = {cluster_name, cluster_issuer_email, project_identifier},starterkit_demo = {name, template_repo, ai_model}anddns_domaininstead of the eight inputs they replace.dns_domainis<dns_subdomain>.<dns_parent_domain>, or just the parent domain when the subdomain is the platform identifier. A caller that relied onplayground_mode = falsesets it explicitly. A caller that relied onuse_global_location = falsewithoutimports.kubernetes_platform.location_namesets it explicitly.payment_method = { value = jsonencode({ kind = "meshPaymentMethod", name = "<identifier>" }) }(orjsonencode(meshstack_payment_method.x.ref)) instead ofpayment_method_identifier; the payment method must belong to the ordering workspace.Verified
tofu validatepasses in the changed directories. Scorecard:bbd_input_orderandbbd_input_defaultspass for both architectures; no regression from the overrides, starter kit demo and DNS domain change.tofu:stackit.rungives<platform identifier>.stackit.run,likvid.stackit.runandmeshcloud-dev.stackit.runkeep their label;a.b.stackit.run,example.comand a label starting with a dash are refused.mesh-projectand the name is known at plan; a later run withimports = nullor another name plans no change; a fresh install pins the derived name.kindand withkind, shows1 to import, 0 to change, 0 to destroyin both cases.0 to add, 2 to change, 0 to destroy(definition and building block). LCF landing zone plans0 to add, 5 to change, 0 to destroy(the extra changes are the control tower definitions, whoseplatform_refis known only after the landing zone block's run), LCF SKE0 to add, 2 to change, 0 to destroy. TCF sandbox landing zone plans0 to add, 3 to change, 0 to destroy; TCF SKE plans the first creation.🤖 Generated with Claude Code