Skip to content

feat(otc): add T Cloud Public landing zone reference architecture (WIP) - #381

Draft
florianow wants to merge 14 commits into
mainfrom
feature/otc-landingzone
Draft

florianow wants to merge 14 commits into
mainfrom
feature/otc-landingzone

Conversation

@florianow

Copy link
Copy Markdown
Collaborator

Adds a T Cloud Public (Open Telekom Cloud) landing zone modeled on stackit-landingzone:

  • modules/otc: registers a custom OTC platform, a default landing zone and the project building block definition.
  • modules/otc/project: backplane (IAM user + group with Security Administrator, optional federated SAML/OIDC identity provider) and a building block that creates <region>_<project>, one IAM group per meshStack role with its role assignments, and records the project's group membership as mappings/<project>.json in an OBS bucket.
  • reference-architectures/otc-landingzone: README, diagram and the orderable building block wiring it all together.

Federated users get their groups from the identity provider's single shared mapping. Instead of every project editing that mapping, each project writes only its own membership object; an aggregator function in the backplane rebuilds the full mapping from all objects.

WIP: the backplane does not yet create the mapping bucket and the FunctionGraph aggregator, and the integration still passes the old password/identity-provider inputs. Not yet run against a real domain.

Adds a T Cloud Public (Open Telekom Cloud) landing zone modeled on
stackit-landingzone:

- modules/otc: registers a custom `OTC` platform, a default landing zone
  and the project building block definition.
- modules/otc/project: backplane (IAM user + group with Security
  Administrator, optional federated SAML/OIDC identity provider) and a
  building block that creates `<region>_<project>`, one IAM group per
  meshStack role with its role assignments, and records the project's
  group membership as `mappings/<project>.json` in an OBS bucket.
- reference-architectures/otc-landingzone: README, diagram and the
  orderable building block wiring it all together.

Federated users get their groups from the identity provider's single
shared mapping. Instead of every project editing that mapping, each
project writes only its own membership object; an aggregator function
in the backplane rebuilds the full mapping from all objects.

WIP: the backplane does not yet create the mapping bucket and the
FunctionGraph aggregator, and the integration still passes the old
password/identity-provider inputs. Not yet run against a real domain.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Scorecard Check

Scorecard run on commit c523030243d44117d879cfb507fde4a0b415013c relative to origin/main

📊 meshstack-hub Module Scorecard

Generated: 2026-10-09 | Modules scanned: 2 | Categories: 7

📋 Per-Module Category Summary

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

Module Overall Core Structure Integration AWS Backplane Azure Backplane GCP Backplane STACKIT Backplane Testing
otc/federation-mapping 🟢 92% 🟢 100% 🟢 100% n/a n/a n/a n/a 🔴 33%
otc/project 🟢 93% 🟢 100% 🟢 100% n/a n/a n/a n/a 🟡 50%

⚠️ 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 📦 🔗 📋 📝 🖼️ 📌 🚦 🎯 🩹 🧼 ❄️ 🔒
otc/federation-mapping 🟢 100% ✅ ✅ ➖ ✅ ✅ ✅ ➖ ✅ ➖ ➖ ➖ ✅
otc/project 🟢 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 included 2/2 🟢 100%
📌 buildingblock/versions.tf present 2/2 🟢 100%
🚦 Child meshstack_building_block asserts a SUCCEEDED run n/a —
🎯 meshStack *_ref attributes use the resource's ref output 2/2 🟢 100%
🩹 Every try() carries a comment saying why n/a —
🧼 Pre-run scripts install no tools on the runner n/a —
❄️ 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 🏷️ 🏢 📤 🔌 📎 🔀 🌱 📋 🏷️ 🧱 🏪 📖 📝 📊 🚫 🔄 🪪
otc/federation-mapping 🟢 100% ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ➖ ➖
otc/project 🟢 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] 1/1 🟢 100%
🪪 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.

Testing — some checks failing

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

Module Score ⚙️ 🧪 🚫 ✅
otc/federation-mapping 🔴 33% ➖ ❌ ✅ ❌
otc/project 🟡 50% ✅ ❌ ✅ ❌

Testing — Summary

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

📈 Overall Summary

Overall Average Score: 93%

Score Distribution

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

@aws-amplify-eu-central-1

Copy link
Copy Markdown

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-381.d1o16zfeoh2slu.amplifyapp.com

State the reasons inline instead of pointing at the STACKIT modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

docs(otc): drop references to other clouds from comments and readmes
@florianow
florianow force-pushed the feature/otc-landingzone branch from 02f7d3a to d1a9644 Compare October 8, 2026 13:21
florianow and others added 12 commits October 8, 2026 15:40
The identity provider's single mapping is no longer written by the
project building blocks. Each project records its group membership as
`mappings/<project>.json` in an OBS bucket, and a new
`otc/federation-mapping` building block runs a FunctionGraph function
that rebuilds the whole mapping from all records, on every bucket event
and hourly. The function acts as an agency, so it holds no key.

The reference architecture now creates a management project as a
meshStack tenant on the new platform and orders the federation mapping
building block on it. The provider resolves its project when it is
configured, so the function has to run in an apply of its own.

Also:
- backplane user authenticates with an access key instead of a password
- providers set `tenant_name` to the region project; AK/SK requires one
- the optional identity provider form has no defaults, so an untouched
  form no longer switches federation on
- domain name examples use a placeholder and accept both name formats

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e identity provider

- `tags.project` and `tags.project_owner_tag_key` are optional, so a
  landing zone ordered before the management project existed runs
  without its Tags being filled in again.
- A chosen protocol without its required fields now fails validation
  with a message saying what to fill in or to clear the input, instead
  of a provider error.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Found in the first meshStack run:
- The `OTC` platform type had to exist up front. `modules/otc` can now
  create it (`otc_platform_type_create`), and the reference
  architecture creates one per landing zone, `OTC-<IDENTIFIER>`, since
  a platform type name is unique across the meshStack instance.
- An `all_projects` role assignment needs the domain ID as well.
- The Tags form no longer requires the management project fields:
  meshStack validates a stored value against the current schema on
  every edit, which rejected landing zones ordered before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Template directives inside a `<<-EOT` heredoc throw off its indentation
stripping, which turned the role table and the sign-in note into an
indented code block in meshPanel. Build those lines in locals instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…on, delete it first

- The run's meshStack token cannot be renewed, so a run that waits past
  its expiry fails and loses the tenant from its state. Only the
  federation mapping building block needs the replicated project, so
  only a landing zone with federation waits for it.
- The management tenant depends on the whole platform integration, so
  a destroy deletes it, and runs the project building block's destroy,
  before the backplane user that destroy authenticates as is gone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
meshPanel counts an empty array as a missing required value, and the
`building_block` and `project` tag maps default to `[]`. The order form
stayed disabled with no field marked until a tag was added to each.
Nothing in the Tags form is required now, and the buildingblock
variable defaults every map, so an empty form plans.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Found ordering a second landing zone into the same meshStack:
- meshStack requires a platform type's display name to be unique too,
  not just its name. `modules/otc` takes it as
  `otc_platform_type_display_name`, and the reference architecture
  names it after the platform.
- The Tags form preset `projectOwner` as the owner tag key, which fails
  the management project with `409 TagValidation` on an instance that
  has no such tag. It is empty by default now.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…deration.dev

TEMPORARY, revert before merging. federation.dev only accepts project
identifiers ending in -dev, -prod or -qa.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…rrectly

Template directives inside the `<<-EOT` heredoc threw off its
indentation stripping, which merged the table rows and the playground
note in meshPanel. Build the conditional parts in locals instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Without an identity provider the landing zone works, but meshStack's
project members never reach T Cloud Public. The summary now says so in a
warning: manage users in the IAM console for the time being, register T
Cloud Public in one of the identity providers the T Cloud blueprints
cover, and fill in the Identity Provider input for the next run. Once
one is connected, a tip names it and links the federation mapping
building block instead.

The text moves to SUMMARY.md.tftpl: it branches, and template
directives inside a heredoc broke its indentation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…hout federation

Without an identity provider, meshStack's project members never reached
the project groups. The project building block now adds each member's
existing IAM user to the group of their role. IAM usernames cannot
contain an `@`, and the provider looks users up by name only, so a
member's IAM user is the one named like the part of their email before
the `@`. meshStack creates no users; a member without an IAM user fails
the run, naming the user.

With federation nothing changes: the identity provider's mapping puts
users into the groups, and no local user is looked up.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… users

Compares running with and without an identity provider, says why the
federation mapping function exists only with one, and why the landing
zone federates virtual users rather than linking IAM users (IAM user
SSO): that would bring back per-user maintenance in T Cloud Public,
with no SCIM to automate it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

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