Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ci/validate_modules.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ check_png_minimization() {

check_terraform_files() {
local buildingblock_path="$1"

# Skip terraform checks for manual building blocks and other non-terraform modules
# This is deliberately naive for the single use case we have right now, we can make this smarter if we have that case more often
if [[ "$buildingblock_path" == *"/meshstack/manual/buildingblock" ]]; then
return 0
fi

local tf_files=("main.tf" "variables.tf" "outputs.tf")

for tf_file in "${tf_files[@]}"; do
Expand Down
26 changes: 26 additions & 0 deletions modules/meshstack/manual/buildingblock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: meshStack Manual Building Block
supportedPlatforms:
- meshstack
description: |
Reference building block demonstrating meshStack's MANUAL implementation type:
selected input types mirrored to outputs, with additional inputs that have no corresponding output.
---
# meshStack Manual Building Block

This building block is a reference implementation demonstrating how meshStack handles the MANUAL implementation type. It exercises output mirroring (outputs copy input values 1:1), the constraint that some input types (e.g. `SINGLE_SELECT`) have no corresponding output type, and the validity of having more inputs than outputs.

Use it to:
- Understand how meshStack handles MANUAL building blocks
- See which input types can be mirrored to outputs
- Validate that extra inputs (with no matching output) are allowed

## Input Types

| Input | Type | Assignment | Mirrored to Output |
|-------|------|-----------|-------------------|
| `text` | `STRING` | `USER_INPUT` | ✅ |
| `flag` | `BOOLEAN` | `USER_INPUT` | ✅ |
| `num` | `INTEGER` | `USER_INPUT` | ✅ |
| `single_select` | `SINGLE_SELECT` | `USER_INPUT` | ❌ (no corresponding output type) |
| `static_note` | `STRING` | `STATIC` | ❌ (extra input without output) |
9 changes: 9 additions & 0 deletions modules/meshstack/manual/e2e/terraform.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 1.0"

required_providers {
meshstack = {
source = "meshcloud/meshstack"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
run "building_block_manual_hub" {
assert {
condition = meshstack_building_block_v2.this.status.status == "SUCCEEDED"
error_message = "manual hub building block expected SUCCEEDED, got ${meshstack_building_block_v2.this.status.status}"
}

assert {
condition = meshstack_building_block_v2.this.status.outputs["text"].value_string == "Hello, Manual World!"
error_message = "manual hub building block expected output text to be 'Hello, Manual World!', got ${meshstack_building_block_v2.this.status.outputs["text"].value_string}"
}

assert {
condition = meshstack_building_block_v2.this.status.outputs["flag"].value_bool == true
error_message = "manual hub building block expected output flag to be true, got ${meshstack_building_block_v2.this.status.outputs["flag"].value_bool}"
}

assert {
condition = meshstack_building_block_v2.this.status.outputs["num"].value_int == 42
error_message = "manual hub building block expected output num to be 42, got ${meshstack_building_block_v2.this.status.outputs["num"].value_int}"
}
}
132 changes: 132 additions & 0 deletions modules/meshstack/manual/meshstack_integration.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
variable "meshstack" {
type = object({
owning_workspace_identifier = string
tags = optional(map(list(string)), {})
})
description = "Shared meshStack context. Tags are optional and propagated to building block definition metadata."
}

variable "hub" {
type = object({
git_ref = optional(string, "main")
bbd_draft = optional(bool, true)
})
default = {}
description = <<-EOT
`git_ref`: Hub release reference. Set to a tag (e.g. 'v1.2.3') or branch or commit sha of the meshstack-hub repo.
`bbd_draft`: If true, the building block definition version is kept in draft mode.
EOT
}

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
git_ref = var.hub.git_ref
}
}

resource "meshstack_building_block_definition" "this" {
metadata = {
owned_by_workspace = var.meshstack.owning_workspace_identifier
tags = var.meshstack.tags
}

spec = {
display_name = "meshStack Manual Building Block"
description = "Reference building block demonstrating the MANUAL implementation type: outputs mirror selected inputs 1:1, with extra inputs (SINGLE_SELECT and STATIC) that have no corresponding output."
target_type = "WORKSPACE_LEVEL"
readme = <<-EOT
This building block demonstrates meshStack's MANUAL implementation type, where platform operators manually confirm execution and output values are copied directly from inputs.

**Use cases:**
- Manual approval workflows where a platform operator reviews and confirms a request
- Processes that require human steps outside of automation (e.g. opening a ticket, configuring a system manually)

**Example — Requesting Manual Access:**
A developer requests access to a system. A platform operator reviews the request, performs the manual steps, and marks the building block as complete — the output mirrors the approved request details.

## Shared Responsibility

| Responsibility | Platform Team | Application Team |
|----------------|:-------------:|:----------------:|
| Complete the building block run | ✅ | ❌ |
| Provide `text`, `flag`, `num`, inputs | ❌ | ✅ |
| Monitor completion status | ❌ | ✅ |
EOT
}

version_spec = {
draft = var.hub.bbd_draft
deletion_mode = "PURGE"
implementation = {
manual = {}
}
inputs = {
text = {
assignment_type = "USER_INPUT"
display_name = "Text"
type = "STRING"
}
flag = {
assignment_type = "USER_INPUT"
display_name = "Flag"
type = "BOOLEAN"
}
num = {
assignment_type = "USER_INPUT"
display_name = "Num"
type = "INTEGER"
}

# TODO: these two currently break the terraform provider because they can't be mapped to an output type
# This is a known issue that needs to be fixed in meshStack
# > produced an unexpected new value:
# .version_spec.outputs: new element "single_select" has appeared.
# .version_spec.outputs: new element "static_note" has appeared.

# single_select = {
# assignment_type = "USER_INPUT"
# display_name = "Single Select"
# selectable_values = ["option1", "option2"]
# type = "SINGLE_SELECT"
# }
# # Static input with no corresponding output — exercises more-inputs-than-outputs
# static_note = {
# assignment_type = "STATIC"
# display_name = "Static Note"
# type = "STRING"
# argument = jsonencode("A static note value")
# }
}
# Output keys must match input keys; types must be compatible with manual mirroring.
# Only text, flag, and num are output — single_select and static_note are intentionally omitted.
outputs = {
text = {
assignment_type = "NONE"
display_name = "Text"
type = "STRING"
}
flag = {
assignment_type = "NONE"
display_name = "Flag"
type = "BOOLEAN"
}
num = {
assignment_type = "NONE"
display_name = "Num"
type = "INTEGER"
}
}
}
}

terraform {
required_providers {
meshstack = {
source = "meshcloud/meshstack"
version = "~> 0.20.0"
}
}
}
Loading