diff --git a/modules/stackit/meshstack_integration.tf b/modules/stackit/meshstack_integration.tf index 614b4eed..3b2f2de8 100644 --- a/modules/stackit/meshstack_integration.tf +++ b/modules/stackit/meshstack_integration.tf @@ -45,13 +45,19 @@ variable "role_mapping" { variable "stackit_project_labels" { type = map(string) default = {} - description = "Additional labels applied to every STACKIT project created by this building block, merged with the `networkArea` label resolved at runtime from the landing zone's tags." + description = "Additional labels applied to every STACKIT project created by this building block." } -variable "stackit_network_area_tag_name" { +variable "stackit_networked_projects_enabled" { + type = bool + default = false + description = "Whether to create a second, `networked` STACKIT Project building block definition and landing zone whose projects are placed in `stackit_network_area_id`. Must be known at plan time (`stackit_network_area_id` itself may only resolve during apply)." +} + +variable "stackit_network_area_id" { type = string default = null - description = "Name of the meshStack landing zone tag whose value is used as the STACKIT project's `networkArea` label. Set to null (default) to skip network area assignment." + description = "STACKIT network area ID applied as the `networkArea` label to projects created through the `networked` landing zone. Only used when `stackit_networked_projects_enabled` is true." } variable "meshstack" { @@ -100,7 +106,8 @@ module "backplane" { workload_identity_federation = { issuer = data.meshstack_integrations.integrations.workload_identity_federation.replicator.issuer subjects = [ - "${trimsuffix(data.meshstack_integrations.integrations.workload_identity_federation.replicator.subject, ":replicator")}:workspace.${var.meshstack.owning_workspace_identifier}.buildingblockdefinition.${meshstack_building_block_definition.this.metadata.uuid}" + for bbd in meshstack_building_block_definition.this : + "${trimsuffix(data.meshstack_integrations.integrations.workload_identity_federation.replicator.subject, ":replicator")}:workspace.${var.meshstack.owning_workspace_identifier}.buildingblockdefinition.${bbd.metadata.uuid}" ] } } @@ -110,11 +117,40 @@ data "meshstack_integrations" "integrations" {} output "building_block_definition" { description = "BBD is consumed in building block compositions." value = { - uuid = meshstack_building_block_definition.this.metadata.uuid - version_ref = var.hub.bbd_draft ? meshstack_building_block_definition.this.version_latest : meshstack_building_block_definition.this.version_latest_release + uuid = meshstack_building_block_definition.this["default"].metadata.uuid + version_ref = var.hub.bbd_draft ? meshstack_building_block_definition.this["default"].version_latest : meshstack_building_block_definition.this["default"].version_latest_release } } +output "service_account_email" { + description = "Email of the backplane STACKIT service account that creates and manages tenant projects." + value = module.backplane.service_account_email +} + +# One STACKIT Project building block definition plus landing zone per project variant. The +# `networked` variant carries the `networkArea` label as a static building block input, so projects +# are placed in the network area without any landing zone tag lookup at run time. +locals { + project_variants = merge( + { + default = { + bbd_display_name = "STACKIT Project" + landingzone_display_name = "STACKIT Sandbox" + landingzone_description = "Creates a STACKIT project in the landing zone folder, with project roles mapped from meshStack project roles. The project is not attached to a network area, so it uses STACKIT's default flat networking." + network_area_id = null + } + }, + var.stackit_networked_projects_enabled ? { + networked = { + bbd_display_name = "STACKIT Networked Project" + landingzone_display_name = "STACKIT Networked" + landingzone_description = "Creates a STACKIT project placed in the shared hub network area, with project roles mapped from meshStack project roles. Order the STACKIT Network building block inside the project to get a routed subnet drawn from the hub's address plan." + network_area_id = var.stackit_network_area_id + } + } : {} + ) +} + resource "meshstack_platform" "stackit" { metadata = { name = var.meshstack.platform_identifier @@ -130,6 +166,8 @@ resource "meshstack_platform" "stackit" { description = "Create a STACKIT project with configurable role-based access control." endpoint = "https://portal.stackit.cloud" + documentation_url = "https://hub.meshcloud.io/reference-architectures/stackit-landingzone" + location_ref = { name = var.meshstack.location_name } @@ -148,16 +186,19 @@ resource "meshstack_platform" "stackit" { } } -resource "meshstack_landingzone" "stackit_default" { +resource "meshstack_landingzone" "this" { + for_each = local.project_variants + metadata = { - name = "${var.meshstack.platform_identifier}-default" + name = "${var.meshstack.platform_identifier}-${each.key}" owned_by_workspace = var.meshstack.owning_workspace_identifier tags = var.meshstack.tags.landingzone } spec = { - display_name = "STACKIT Default" - description = "Default landing zone for STACKIT projects." + display_name = each.value.landingzone_display_name + description = each.value.landingzone_description + info_link = "https://hub.meshcloud.io/reference-architectures/stackit-landingzone" automate_deletion_approval = true automate_deletion_replication = true @@ -170,19 +211,21 @@ resource "meshstack_landingzone" "stackit_default" { } mandatory_building_block_refs = [ - { uuid = meshstack_building_block_definition.this.metadata.uuid } + { uuid = meshstack_building_block_definition.this[each.key].metadata.uuid } ] } } resource "meshstack_building_block_definition" "this" { + for_each = local.project_variants + metadata = { owned_by_workspace = var.meshstack.owning_workspace_identifier tags = var.meshstack.tags.building_block } spec = { - display_name = "STACKIT Project" + display_name = each.value.bbd_display_name symbol = "https://raw.githubusercontent.com/meshcloud/meshstack-hub/${var.hub.git_ref}/modules/stackit/project/buildingblock/logo.png" description = "Creates a new STACKIT project and manages user access permissions with configurable role-based access control." support_url = "https://portal.stackit.cloud" @@ -211,7 +254,7 @@ resource "meshstack_building_block_definition" "this" { } } - inputs = merge({ + inputs = { parent_container_id = { display_name = "Parent Container ID" description = "Default parent container ID (organization or folder) where the project will be created." @@ -297,35 +340,15 @@ resource "meshstack_building_block_definition" "this" { labels = { display_name = "Labels" - description = "Additional labels applied to the STACKIT project, merged with the `networkArea` label resolved at runtime from the landing zone's tags." + description = "Labels applied to the STACKIT project, including the `networkArea` label for the networked variant." type = "CODE" assignment_type = "STATIC" - argument = jsonencode(jsonencode(var.stackit_project_labels)) + argument = jsonencode(jsonencode(merge( + var.stackit_project_labels, + each.value.network_area_id != null ? { networkArea = each.value.network_area_id } : {} + ))) } - - workspace_identifier = { - display_name = "Workspace Identifier" - description = "meshStack workspace identifier, used to look up this project's landing zone tags at runtime." - type = "STRING" - assignment_type = "WORKSPACE_IDENTIFIER" - } - - platform_identifier = { - display_name = "Platform Identifier" - description = "meshStack platform identifier, used to look up this project's landing zone tags at runtime." - type = "STRING" - assignment_type = "FULL_PLATFORM_IDENTIFIER" - } - - }, var.stackit_network_area_tag_name != null ? { - network_area_tag_name = { - display_name = "Network Area Tag Name" - description = "Name of the meshStack landing zone tag whose value is used as the STACKIT project's `networkArea` label." - type = "STRING" - assignment_type = "STATIC" - argument = jsonencode(var.stackit_network_area_tag_name) - } - } : {}) + } outputs = { project_url = { @@ -358,9 +381,6 @@ resource "meshstack_building_block_definition" "this" { assignment_type = "SUMMARY" } } - - # TENANT_LIST/LANDINGZONE_LIST: needed by meshstack_tenant/meshstack_landingzone data sources for network area tag lookup. - permissions = ["TENANT_LIST", "LANDINGZONE_LIST"] } } diff --git a/modules/stackit/project/buildingblock/README.md b/modules/stackit/project/buildingblock/README.md index 075786d8..262c4f4b 100644 --- a/modules/stackit/project/buildingblock/README.md +++ b/modules/stackit/project/buildingblock/README.md @@ -57,24 +57,19 @@ No modules. |------|------| | [stackit_authorization_project_role_assignment.role_assignments](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/authorization_project_role_assignment) | resource | | [stackit_resourcemanager_project.project](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/resourcemanager_project) | resource | -| [meshstack_landingzone.this](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/data-sources/landingzone) | data source | -| [meshstack_tenant.this](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/data-sources/tenant) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [environment](#input\_environment) | The environment type (production, staging, development). If not set, uses parent\_container\_id directly. | `string` | `null` | no | -| [labels](#input\_labels) | Additional labels to apply to the project, merged with the `networkArea` label resolved from the landing zone's tags. | `map(string)` | n/a | yes | -| [network\_area\_tag\_name](#input\_network\_area\_tag\_name) | Name of the meshStack landing zone tag whose value is used as the STACKIT project's `networkArea` label. Set to null (default) to skip network area assignment — projects remain usable without a network area. | `string` | `null` | no | +| [labels](#input\_labels) | Labels to apply to the project. Includes the `networkArea` label when the building block definition is wired to a network area. | `map(string)` | n/a | yes | | [parent\_container\_id](#input\_parent\_container\_id) | The parent container ID (organization or folder) where the project will be created. | `string` | n/a | yes | | [parent\_container\_ids](#input\_parent\_container\_ids) | Parent container IDs for different environments. If environment is set, the corresponding container ID will be used. |
object({
production = optional(string)
staging = optional(string)
development = optional(string)
}) | `{}` | no |
-| [platform\_identifier](#input\_platform\_identifier) | meshStack platform identifier, used to look up this project's landing zone tags at runtime. | `string` | n/a | yes |
| [project\_name](#input\_project\_name) | The name of the StackIt project to create. | `string` | n/a | yes |
| [role\_mapping](#input\_role\_mapping) | Maps meshStack roles from `users[*].roles` to STACKIT project roles. Values can be built-in STACKIT roles or custom STACKIT role names. Unknown meshStack roles are ignored. | `map(list(string))` | n/a | yes |
| [service\_account\_email](#input\_service\_account\_email) | Email of the STACKIT service account for WIF-based authentication and project ownership. | `string` | n/a | yes |
| [users](#input\_users) | List of users from the authoritative system. Each user's `roles` are meshStack roles that are mapped to STACKIT project roles via `role_mapping`. | list(object({
meshIdentifier = string
username = string
firstName = string
lastName = string
email = string
euid = string
roles = list(string)
})) | n/a | yes |
-| [workspace\_identifier](#input\_workspace\_identifier) | meshStack workspace identifier, used to look up this project's landing zone tags at runtime. | `string` | n/a | yes |
## Outputs
@@ -84,5 +79,5 @@ No modules.
| [project\_id](#output\_project\_id) | The UUID of the created StackIt project. |
| [project\_name](#output\_project\_name) | The name of the created StackIt project. |
| [project\_url](#output\_project\_url) | The deep link URL to access the project in the StackIt portal. |
-| [summary](#output\_summary) | Summary of STACKIT organization membership onboarding for assigned project users. |
+| [summary](#output\_summary) | Summary of the created project and STACKIT organization membership onboarding for assigned project users. |
\ No newline at end of file
diff --git a/modules/stackit/project/buildingblock/SUMMARY.md.tftpl b/modules/stackit/project/buildingblock/SUMMARY.md.tftpl
new file mode 100644
index 00000000..ca939c5b
--- /dev/null
+++ b/modules/stackit/project/buildingblock/SUMMARY.md.tftpl
@@ -0,0 +1,11 @@
+# Project: **${project_name}**
+
+## Details
+
+| Property | Value |
+|----------|-------|
+| **Project ID** | `${project_id}` |
+| **Container ID** | `${container_id}` |
+| **Portal** | [Open in STACKIT Portal](${project_url}) |
+
+${membership_summary}
diff --git a/modules/stackit/project/buildingblock/main.tf b/modules/stackit/project/buildingblock/main.tf
index 8aea23d7..de99b36a 100644
--- a/modules/stackit/project/buildingblock/main.tf
+++ b/modules/stackit/project/buildingblock/main.tf
@@ -1,36 +1,7 @@
-# TODO: migrate to the meshstack_tenant_v4 data source once meshStack supports a tenant UUID
-# as a building block input (currently under development). That will let us look up the
-# tenant from a single identifier instead of the three separate identity inputs below
-# (project_name/workspace_identifier/platform_identifier).
-data "meshstack_tenant" "this" {
- lifecycle {
- enabled = var.network_area_tag_name != null
- }
-
- metadata = {
- owned_by_project = var.project_name
- owned_by_workspace = var.workspace_identifier
- platform_identifier = var.platform_identifier
- }
-}
-
-data "meshstack_landingzone" "this" {
- lifecycle {
- enabled = var.network_area_tag_name != null
- }
-
- metadata = {
- name = data.meshstack_tenant.this.spec.landing_zone_ref.name
- }
-}
-
locals {
# Determine the parent container ID based on environment
selected_parent_container_id = var.environment != null ? lookup(var.parent_container_ids, var.environment, var.parent_container_id) : var.parent_container_id
- network_area_id = var.network_area_tag_name != null ? data.meshstack_landingzone.this.metadata.tags[var.network_area_tag_name][0] : null
- project_labels = merge(var.labels, local.network_area_id != null ? { networkArea = local.network_area_id } : {})
-
users_with_stackit_roles = [
for user in var.users : {
email = user.email
@@ -59,7 +30,7 @@ resource "stackit_resourcemanager_project" "project" {
owner_email = var.service_account_email
# Only set labels if there are actually labels to set
- labels = length(local.project_labels) > 0 ? local.project_labels : null
+ labels = length(var.labels) > 0 ? var.labels : null
}
# User role assignments (experimental IAM feature)
diff --git a/modules/stackit/project/buildingblock/outputs.tf b/modules/stackit/project/buildingblock/outputs.tf
index 9bec4a92..213ba0c5 100644
--- a/modules/stackit/project/buildingblock/outputs.tf
+++ b/modules/stackit/project/buildingblock/outputs.tf
@@ -19,6 +19,12 @@ output "project_url" {
}
output "summary" {
- value = fileexists("${path.module}/stackit_organization_membership_summary.md") ? file("${path.module}/stackit_organization_membership_summary.md") : "STACKIT organization membership summary was not generated."
- description = "Summary of STACKIT organization membership onboarding for assigned project users."
-}
\ No newline at end of file
+ description = "Summary of the created project and STACKIT organization membership onboarding for assigned project users."
+ value = templatefile("${path.module}/SUMMARY.md.tftpl", {
+ project_name = stackit_resourcemanager_project.project.name
+ project_id = stackit_resourcemanager_project.project.project_id
+ container_id = stackit_resourcemanager_project.project.container_id
+ project_url = "https://portal.stackit.cloud/projects/${stackit_resourcemanager_project.project.project_id}"
+ membership_summary = fileexists("${path.module}/stackit_organization_membership_summary.md") ? file("${path.module}/stackit_organization_membership_summary.md") : "STACKIT organization membership summary was not generated."
+ })
+}
diff --git a/modules/stackit/project/buildingblock/variables.tf b/modules/stackit/project/buildingblock/variables.tf
index 7d24c640..b6cab1ee 100644
--- a/modules/stackit/project/buildingblock/variables.tf
+++ b/modules/stackit/project/buildingblock/variables.tf
@@ -35,25 +35,7 @@ variable "service_account_email" {
variable "labels" {
type = map(string)
nullable = false
- description = "Additional labels to apply to the project, merged with the `networkArea` label resolved from the landing zone's tags."
-}
-
-variable "workspace_identifier" {
- type = string
- nullable = false
- description = "meshStack workspace identifier, used to look up this project's landing zone tags at runtime."
-}
-
-variable "platform_identifier" {
- type = string
- nullable = false
- description = "meshStack platform identifier, used to look up this project's landing zone tags at runtime."
-}
-
-variable "network_area_tag_name" {
- type = string
- default = null
- description = "Name of the meshStack landing zone tag whose value is used as the STACKIT project's `networkArea` label. Set to null (default) to skip network area assignment — projects remain usable without a network area."
+ description = "Labels to apply to the project. Includes the `networkArea` label when the building block definition is wired to a network area."
}
variable "users" {
diff --git a/reference-architectures/stackit-landingzone/README.md b/reference-architectures/stackit-landingzone/README.md
index 225160fa..73e647f9 100644
--- a/reference-architectures/stackit-landingzone/README.md
+++ b/reference-architectures/stackit-landingzone/README.md
@@ -80,8 +80,10 @@ When a **network** configuration is provided, it additionally:
5. Registers the [`stackit/network`](../../modules/stackit/network) building block definition
(`TENANT_LEVEL`) so application teams can self-service order routed networks (spokes) inside
their STACKIT projects, drawing from the hub's address plan.
-6. Provisions an additional **networked landing zone**, tagged with the hub's network area ID, so
- new STACKIT projects created against it are placed in the hub's network area.
+6. Provisions an additional **networked project definition and landing zone**. The networked
+ `STACKIT Project` building block definition carries the hub's network area ID as a static
+ `networkArea` label, so new STACKIT projects created against that landing zone are placed in the
+ hub's network area.
## Getting Started
@@ -96,7 +98,7 @@ When a **network** configuration is provided, it additionally:
Order the **STACKIT Landing Zone** building block once per workspace. Without a network
configuration it creates the platform and default landing zone. With a network configuration it
-additionally creates the hub network area instance, the networked landing zone, and registers the
+additionally creates the hub network area instance, the networked project definition and landing zone, and registers the
spoke `stackit/network` building block in the same apply. Application teams can then request
projects and — when networking is enabled — order `stackit/network` inside their own STACKIT
projects once those projects exist.
diff --git a/reference-architectures/stackit-landingzone/buildingblock/README.md b/reference-architectures/stackit-landingzone/buildingblock/README.md
index e7fc4157..dee9862e 100644
--- a/reference-architectures/stackit-landingzone/buildingblock/README.md
+++ b/reference-architectures/stackit-landingzone/buildingblock/README.md
@@ -50,18 +50,16 @@ The user-facing readme is maintained inline in the `readme` field of the
| Name | Type |
|------|------|
| [meshstack_building_block.network_area_hub](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/building_block) | resource |
-| [meshstack_landingzone.networked](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/landingzone) | resource |
| [meshstack_location.this](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/location) | resource |
| [stackit_resourcemanager_folder.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/resourcemanager_folder) | resource |
| [stackit_resourcemanager_project.foundation](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/resourcemanager_project) | resource |
-| [meshstack_landingzone.foundation_default](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/data-sources/landingzone) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [hub](#input\_hub) | `git_ref`: meshstack-hub reference used to source the nested foundation, network-area, and network integration modules. `const` so it can be interpolated into the module source at init time.object({
git_ref = optional(string, "main")
bbd_draft = optional(bool, true)
}) | {
"bbd_draft": true,
"git_ref": "main"
} | no |
-| [network](#input\_network) | Optional hub-and-spoke network topology. Leave unset (null) to deploy only the sandbox landing zone. When set, additionally provisions a shared hub network area with the given address plan (`hub_*` fields), registers the self-service spoke `STACKIT Network` building block (`tenant_network_*` prefix bounds), and creates a `networked` landing zone (tagged via `network_area_tag_name`) whose projects are placed in the hub network area. | object({
network_area_tag_name = optional(string, "StackitNetworkArea")
hub_network_area_name = optional(string, "hub")
hub_network_ranges = optional(list(string), ["10.0.0.0/16"])
hub_transfer_network = optional(string, "10.1.255.0/24")
hub_min_prefix_length = optional(number, 24)
hub_max_prefix_length = optional(number, 28)
hub_default_prefix_length = optional(number, 28)
hub_default_nameservers = optional(list(string), [])
tenant_network_min_prefix_length = optional(number, 24)
tenant_network_max_prefix_length = optional(number, 28)
}) | `null` | no |
+| [network](#input\_network) | Optional hub-and-spoke network topology. Leave unset (null) to deploy only the sandbox landing zone. When set, additionally provisions a shared hub network area with the given address plan (`hub_*` fields), registers the self-service spoke `STACKIT Network` building block (`tenant_network_*` prefix bounds), and adds a dedicated `networked` STACKIT Project building block definition and landing zone whose projects are placed in the hub network area. | object({
hub_network_area_name = optional(string, "hub")
hub_network_ranges = optional(list(string), ["10.0.0.0/16"])
hub_transfer_network = optional(string, "10.1.255.0/24")
hub_min_prefix_length = optional(number, 24)
hub_max_prefix_length = optional(number, 28)
hub_default_prefix_length = optional(number, 28)
hub_default_nameservers = optional(list(string), [])
tenant_network_min_prefix_length = optional(number, 24)
tenant_network_max_prefix_length = optional(number, 28)
}) | `null` | no |
| [platform\_identifier](#input\_platform\_identifier) | Identifier for the STACKIT sandbox platform created in meshStack (letters, digits and dashes only). | `string` | n/a | yes |
| [role\_mapping](#input\_role\_mapping) | Default mapping from meshStack roles to STACKIT project roles for the nested STACKIT Project integration. Values can be built-in STACKIT roles or custom STACKIT role names. | `map(list(string))` | n/a | yes |
| [stackit\_org](#input\_stackit\_org) | STACKIT organization UUID under which the landing-zone folder, foundation project and tenant projects are created. | `string` | n/a | yes |
diff --git a/reference-architectures/stackit-landingzone/buildingblock/SUMMARY.md.tftpl b/reference-architectures/stackit-landingzone/buildingblock/SUMMARY.md.tftpl
index a8d028ef..92c16729 100644
--- a/reference-architectures/stackit-landingzone/buildingblock/SUMMARY.md.tftpl
+++ b/reference-architectures/stackit-landingzone/buildingblock/SUMMARY.md.tftpl
@@ -4,11 +4,14 @@
| Property | Value |
|----------|-------|
+| **Organization** | [Open in STACKIT Portal](${organization_url}) (`${organization_id}`) |
+| **Landing Zone Folder** | [Open in STACKIT Portal](${lz_folder_url}) (`${lz_folder_container_id}`) |
| **Foundation Project** | [Open in STACKIT Portal](${foundation_project_url}) (`${foundation_project_id}`) |
-| **Landing Zone Folder** | `${lz_folder_container_id}` |
+| **Foundation Project Service Account** | [Open in STACKIT Portal](${service_account_url}) (`${service_account_email}`) |
%{ if network_enabled ~}
+| **Hub Network Area** | [Open in STACKIT Portal](${network_area_url}) (`${network_area_id}`) |
+| **Hub Network Area Building Block** | @buildingblock[${network_area_hub_uuid}] |
| **Networked Landing Zone** | `${networked_landingzone_name}` |
-| **Hub Network Area** | @buildingblock[${network_area_hub_uuid}] |
%{ endif ~}
%{ if network_enabled ~}
diff --git a/reference-architectures/stackit-landingzone/buildingblock/main.tf b/reference-architectures/stackit-landingzone/buildingblock/main.tf
index 734156e5..2f141a07 100644
--- a/reference-architectures/stackit-landingzone/buildingblock/main.tf
+++ b/reference-architectures/stackit-landingzone/buildingblock/main.tf
@@ -1,6 +1,9 @@
locals {
# Hub-and-spoke networking is deployed only when the operator supplies a `network` object.
network_enabled = var.network != null
+
+ # Only resolvable once the hub network area building block has completed.
+ network_area_id = local.network_enabled ? jsondecode(meshstack_building_block.network_area_hub[0].status.outputs["network_area_id"].value) : null
}
# ── Sandbox landing zone foundation (always deployed) ──
@@ -42,7 +45,11 @@ module "stackit_integration" {
stackit_service_account_name = substr(var.platform_identifier, 0, 20)
role_mapping = var.role_mapping
stackit_organization_onboarding_enabled = var.stackit_organization_onboarding_enabled
- stackit_network_area_tag_name = local.network_enabled ? var.network.network_area_tag_name : null
+
+ # The networked project definition places its projects in the hub network area via a static
+ # `networkArea` label, so no landing zone tag (and no tag definition) is involved.
+ stackit_networked_projects_enabled = local.network_enabled
+ stackit_network_area_id = local.network_area_id
hub = var.hub
@@ -117,35 +124,3 @@ resource "meshstack_building_block" "network_area_hub" {
}
}
}
-
-# Looks up the default landing zone that `module.stackit_integration` already registered, without
-# needing new outputs threaded through it. Used below only as an input into the independent
-# `networked` landing zone — never fed back into the integration itself, which would create a cycle.
-data "meshstack_landingzone" "foundation_default" {
- count = local.network_enabled ? 1 : 0
- metadata = { name = "${var.platform_identifier}-default" }
- depends_on = [module.stackit_integration]
-}
-
-resource "meshstack_landingzone" "networked" {
- count = local.network_enabled ? 1 : 0
-
- metadata = {
- name = "${var.platform_identifier}-networked"
- owned_by_workspace = var.workspace
- tags = merge(var.tags.landingzone, {
- (var.network.network_area_tag_name) = [jsondecode(meshstack_building_block.network_area_hub[0].status.outputs["network_area_id"].value)]
- })
- }
-
- spec = {
- display_name = "STACKIT Networked"
- description = "STACKIT landing zone whose projects are placed in the hub network area."
- automate_deletion_approval = true
- automate_deletion_replication = true
-
- platform_ref = data.meshstack_landingzone.foundation_default[0].spec.platform_ref
- platform_properties = { custom = {} }
- mandatory_building_block_refs = data.meshstack_landingzone.foundation_default[0].spec.mandatory_building_block_refs
- }
-}
diff --git a/reference-architectures/stackit-landingzone/buildingblock/outputs.tf b/reference-architectures/stackit-landingzone/buildingblock/outputs.tf
index db9506a6..88929d13 100644
--- a/reference-architectures/stackit-landingzone/buildingblock/outputs.tf
+++ b/reference-architectures/stackit-landingzone/buildingblock/outputs.tf
@@ -16,12 +16,20 @@ output "foundation_project_url" {
output "summary" {
description = "Summary of the meshStack resources created by this reference architecture."
value = templatefile("${path.module}/SUMMARY.md.tftpl", {
- platform_identifier = var.platform_identifier
- foundation_project_id = stackit_resourcemanager_project.foundation.project_id
- foundation_project_url = "https://portal.stackit.cloud/projects/${stackit_resourcemanager_project.foundation.project_id}"
- lz_folder_container_id = stackit_resourcemanager_folder.this.container_id
+ platform_identifier = var.platform_identifier
+ organization_id = var.stackit_org
+ organization_url = "https://portal.stackit.cloud/dashboard?organization=${var.stackit_org}"
+ lz_folder_container_id = stackit_resourcemanager_folder.this.container_id
+ lz_folder_url = "https://portal.stackit.cloud/dashboard?organization=${var.stackit_org}&folder=${stackit_resourcemanager_folder.this.folder_id}"
+ foundation_project_id = stackit_resourcemanager_project.foundation.project_id
+ foundation_project_url = "https://portal.stackit.cloud/projects/${stackit_resourcemanager_project.foundation.project_id}"
+ service_account_email = module.stackit_integration.service_account_email
+ service_account_url = "https://portal.stackit.cloud/service-accounts/${module.stackit_integration.service_account_email}/overview?project=${stackit_resourcemanager_project.foundation.project_id}"
+
network_enabled = local.network_enabled
- networked_landingzone_name = local.network_enabled ? meshstack_landingzone.networked[0].metadata.name : ""
+ networked_landingzone_name = local.network_enabled ? "${var.platform_identifier}-networked" : ""
network_area_hub_uuid = local.network_enabled ? meshstack_building_block.network_area_hub[0].metadata.uuid : ""
+ network_area_id = local.network_enabled ? local.network_area_id : ""
+ network_area_url = local.network_enabled ? "https://portal.stackit.cloud/network-area/network-areas/${local.network_area_id}/overview?organization=${var.stackit_org}" : ""
})
}
diff --git a/reference-architectures/stackit-landingzone/buildingblock/variables.tf b/reference-architectures/stackit-landingzone/buildingblock/variables.tf
index 35074ec9..3b23892f 100644
--- a/reference-architectures/stackit-landingzone/buildingblock/variables.tf
+++ b/reference-architectures/stackit-landingzone/buildingblock/variables.tf
@@ -68,7 +68,6 @@ variable "stackit_organization_onboarding_enabled" {
variable "network" {
type = object({
- network_area_tag_name = optional(string, "StackitNetworkArea")
hub_network_area_name = optional(string, "hub")
hub_network_ranges = optional(list(string), ["10.0.0.0/16"])
hub_transfer_network = optional(string, "10.1.255.0/24")
@@ -80,7 +79,7 @@ variable "network" {
tenant_network_max_prefix_length = optional(number, 28)
})
default = null
- description = "Optional hub-and-spoke network topology. Leave unset (null) to deploy only the sandbox landing zone. When set, additionally provisions a shared hub network area with the given address plan (`hub_*` fields), registers the self-service spoke `STACKIT Network` building block (`tenant_network_*` prefix bounds), and creates a `networked` landing zone (tagged via `network_area_tag_name`) whose projects are placed in the hub network area."
+ description = "Optional hub-and-spoke network topology. Leave unset (null) to deploy only the sandbox landing zone. When set, additionally provisions a shared hub network area with the given address plan (`hub_*` fields), registers the self-service spoke `STACKIT Network` building block (`tenant_network_*` prefix bounds), and adds a dedicated `networked` STACKIT Project building block definition and landing zone whose projects are placed in the hub network area."
}
variable "hub" {
diff --git a/reference-architectures/stackit-landingzone/meshstack_integration.tf b/reference-architectures/stackit-landingzone/meshstack_integration.tf
index c80eeef0..2bea9dfe 100644
--- a/reference-architectures/stackit-landingzone/meshstack_integration.tf
+++ b/reference-architectures/stackit-landingzone/meshstack_integration.tf
@@ -76,15 +76,15 @@ resource "meshstack_building_block_definition" "this" {
**Example 2: Bootstrap with hub-and-spoke networking**
A platform engineer provides a **network** configuration (CIDR plan, prefix bounds). In addition
to the sandbox platform, the building block provisions the hub network area with the chosen
- address plan, registers the **STACKIT Network** building block, and creates a `networked` landing
- zone. Application teams can then self-service order routed spoke networks inside their projects.
+ address plan, registers the **STACKIT Network** building block, and adds a dedicated `networked`
+ STACKIT Project building block definition plus landing zone whose projects are placed in the hub
+ network area. Application teams can then self-service order routed spoke networks inside their projects.
A **network** configuration looks like this (sensible example values shown — adapt them to your
own address plan):
```json
{
- "network_area_tag_name": "StackitNetworkArea",
"hub_network_area_name": "hub",
"hub_network_ranges": ["10.0.0.0/16"],
"hub_transfer_network": "10.1.255.0/24",
@@ -106,9 +106,10 @@ resource "meshstack_building_block_definition" "this" {
project-creation service account and other landing-zone core assets.
- **STACKIT Project platform** – the `STACKIT Project` building block definition, platform and default landing zone,
including the project-creation service account provisioned in the foundation project.
- - **Hub network area + spoke network building block + networked landing zone** *(only when a
- network configuration is provided)* – the shared hub address plan, the self-service
- `STACKIT Network` building block, and a landing zone that places projects into the hub.
+ - **Hub network area + spoke network building block + networked project definition and landing
+ zone** *(only when a network configuration is provided)* – the shared hub address plan, the
+ self-service `STACKIT Network` building block, and a second `STACKIT Networked Project`
+ building block definition plus landing zone that places projects into the hub network area.
## 🔑 Authentication