Skip to content
Draft
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
29 changes: 14 additions & 15 deletions modules/aws/agentic-coding-sandbox/buildingblock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Before deploying this building block:
2. ✅ Import [AWS Budget Alert Building Block](https://hub.meshcloud.io/definitions/aws-budget-alert) from meshStack Hub into your meshStack
3. ✅ Import [AWS Enable Opt-In Region building block](https://hub.meshcloud.io/definitions/aws-opt-in-region) from meshStack Hub into your meshStack
4. ✅ Configure the `composition_config_yaml` with the correct UUIDs and identifiers
5. ✅ Configure an meshStack API key for the composition with admin permissions for projects, tenants, and building blocks
5. ✅ Configure an meshStack API key for the composition with admin permissions for projects, tenants, and building blocks, and with permission to list platforms — the composition resolves the configured platform identifier to a platform reference

## What This Building Block Does

Expand All @@ -40,16 +40,14 @@ The `composition_config_yaml` variable must contain:

```yaml
landing_zone:
landing_zone_identifier: "your-bedrock-landing-zone-id" # From your AWS Bedrock LZ deployment
platform_identifier: "your-aws-platform-id" # Your AWS platform identifier
landing_zone_identifier: "your-bedrock-landing-zone-id" # From your AWS Bedrock LZ deployment
platform_identifier: "your-aws-platform.your-location" # Full platform identifier, <platform-name>.<location-name>

budget_alert_building_block:
definition_uuid: "uuid-from-meshstack-hub" # UUID from AWS Budget Alert BB deployment
definition_version: 1 # Version from your deployment
definition_version_uuid: "uuid-from-meshstack" # Version UUID of the AWS Budget Alert BBD

enable_eu_south_2_region_building_block:
definition_uuid: "uuid-from-meshstack-hub" # UUID from AWS Enable Opt-In Region BB deployment
definition_version: 1 # Version from your deployment
definition_version_uuid: "uuid-from-meshstack" # Version UUID of the AWS Enable Opt-In Region BBD

project: # Optional project configuration
default_tags:
Expand All @@ -60,10 +58,10 @@ project: # Optional project configurati

### How to Get the Required Values

1. **Landing Zone Identifiers**: Check your AWS platform configuration in meshStack
2. **Building Block UUIDs**: After importing building blocks from meshStack Hub, find their UUIDs in:
- meshStack Admin Area → Building Block Definitions
- Or via meshStack API: `GET /api/meshobjects/meshbuildingblockdefinitions`
1. **Landing Zone and Platform Identifiers**: Check your AWS platform configuration in meshStack. The platform identifier is the full `<platform-name>.<location-name>`.
2. **Building Block Definition Version UUIDs**: After importing the building blocks from meshStack Hub, look up the UUID of the definition *version* you want to provision (not the UUID of the definition itself) in:
- meshStack Admin Area → Building Block Definitions → the definition's version
- Or via meshStack API: `GET /api/meshobjects/meshbuildingblockdefinitions`, and read the `uuid` of the version

## User Inputs

Expand All @@ -77,7 +75,7 @@ End users provide:

| Name | Version |
|------|---------|
| <a name="requirement_meshstack"></a> [meshstack](#requirement\_meshstack) | >= 0.7.1 |
| <a name="requirement_meshstack"></a> [meshstack](#requirement\_meshstack) | >= 0.24.3 |

## Modules

Expand All @@ -87,18 +85,19 @@ No modules.

| Name | Type |
|------|------|
| [meshstack_buildingblock.budget_alert](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/buildingblock) | resource |
| [meshstack_buildingblock.enable_eu_south_2_region](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/buildingblock) | resource |
| [meshstack_building_block.budget_alert](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/building_block) | resource |
| [meshstack_building_block.enable_eu_south_2_region](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/building_block) | resource |
| [meshstack_project.sandbox](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/project) | resource |
| [meshstack_tenant.sandbox](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/resources/tenant) | resource |
| [random_string.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [meshstack_platforms.available](https://registry.terraform.io/providers/meshcloud/meshstack/latest/docs/data-sources/platforms) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_budget_amount"></a> [budget\_amount](#input\_budget\_amount) | Monthly budget amount. You will receive an alert when the budget is exceeded. | `number` | n/a | yes |
| <a name="input_composition_config_yaml"></a> [composition\_config\_yaml](#input\_composition\_config\_yaml) | YAML configuration for landing zone and building blocks. Expected structure:<pre>yaml<br/>landing_zone:<br/> landing_zone_identifier: "my-landing-zone"<br/> platform_identifier: "my-platform"<br/>budget_alert_building_block:<br/> definition_uuid: "uuid-here"<br/> definition_version: 1<br/>enable_eu_south_2_region_building_block:<br/> definition_uuid: "uuid-here"<br/> definition_version: 1<br/>project:<br/> default_tags:<br/> environment: "sandbox"<br/> cost_center: "engineering"<br/> owner_tag_key: "project_owner" # optional, if not set no project owner tag will be set</pre> | `string` | n/a | yes |
| <a name="input_composition_config_yaml"></a> [composition\_config\_yaml](#input\_composition\_config\_yaml) | YAML configuration for landing zone and building blocks. Expected structure:<pre>yaml<br/>landing_zone:<br/> landing_zone_identifier: "my-landing-zone"<br/> platform_identifier: "my-platform.my-location" # full platform identifier, <platform-name>.<location-name><br/>budget_alert_building_block:<br/> definition_version_uuid: "uuid-here" # uuid of the building block definition *version* to provision<br/>enable_eu_south_2_region_building_block:<br/> definition_version_uuid: "uuid-here"<br/>project:<br/> default_tags:<br/> environment: "sandbox"<br/> cost_center: "engineering"<br/> owner_tag_key: "project_owner" # optional, if not set no project owner tag will be set</pre> | `string` | n/a | yes |
| <a name="input_username"></a> [username](#input\_username) | meshStack username of the project contact. This should be an email. | `string` | n/a | yes |
| <a name="input_workspace_identifier"></a> [workspace\_identifier](#input\_workspace\_identifier) | Identifier for the owning workspace | `string` | n/a | yes |

Expand Down
91 changes: 49 additions & 42 deletions modules/aws/agentic-coding-sandbox/buildingblock/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ provider "meshstack" {
# configured via env vars
}

## Note: all of this is arguably a not so pretty workaround for missing data objects in meshStack's terraform provider
## to locate the right BBDs and LZs.
## But for now this provides a suitable way to have a single platform operator input for configuring the BBD after
## importing it from meshStack Hub, so we'll run with this approach for now until we discover something better.
## Note: this composition is configured through a single flat YAML input so that a platform operator can
## configure it in one place right after importing it from meshStack Hub. It is written in the most
## human-readable form the provider can actually resolve: the platform and the landing zone are named by
## their identifiers, while the building block definition versions have to be uuids because the provider
## has no data source that resolves a definition (or one of its versions) by uuid or by name.

locals {
# Parse YAML configuration - validation is now handled at the variable level
Expand All @@ -15,11 +16,8 @@ locals {
landing_zone_identifier = local.config.landing_zone.landing_zone_identifier
platform_identifier = local.config.landing_zone.platform_identifier

budget_alert_definition_uuid = local.config.budget_alert_building_block.definition_uuid
budget_alert_definition_version = local.config.budget_alert_building_block.definition_version

enable_eu_south_2_region_definition_uuid = local.config.enable_eu_south_2_region_building_block.definition_uuid
enable_eu_south_2_region_definition_version = local.config.enable_eu_south_2_region_building_block.definition_version
budget_alert_definition_version_uuid = local.config.budget_alert_building_block.definition_version_uuid
enable_eu_south_2_region_definition_version_uuid = local.config.enable_eu_south_2_region_building_block.definition_version_uuid

# Project configuration with safe defaults
project_config = try(local.config.project, {})
Expand Down Expand Up @@ -64,62 +62,71 @@ resource "meshstack_project" "sandbox" {
}


# meshstack_tenant runs on the meshTenant v4 API, which references its platform by uuid. Platform
# operators configure this composition with a platform identifier, so look the platform up by its
# full identifier (`<platform-name>.<location-name>`) and reuse the ref the data source computes.
data "meshstack_platforms" "available" {}

locals {
platform_ref = one([
for platform in data.meshstack_platforms.available.platforms : platform.ref
if platform.identifier == local.platform_identifier
])
}

resource "meshstack_tenant" "sandbox" {
metadata = {
owned_by_workspace = meshstack_project.sandbox.metadata.owned_by_workspace
owned_by_project = meshstack_project.sandbox.metadata.name
platform_identifier = local.platform_identifier
owned_by_workspace = meshstack_project.sandbox.metadata.owned_by_workspace
owned_by_project = meshstack_project.sandbox.metadata.name
}

spec = {
landing_zone_identifier = local.landing_zone_identifier
platform_ref = local.platform_ref
landing_zone_ref = {
name = local.landing_zone_identifier
}
}
}


# NOTE: must use bb v1 resource because v2 requires a tenant uuid
# but the tenant v4 api that delivers the uuid is not supported by our terraform provider yet
resource "meshstack_buildingblock" "budget_alert" {
metadata = {
definition_uuid = local.budget_alert_definition_uuid
definition_version = local.budget_alert_definition_version
tenant_identifier = "${meshstack_tenant.sandbox.metadata.owned_by_workspace}.${meshstack_tenant.sandbox.metadata.owned_by_project}.${meshstack_tenant.sandbox.metadata.platform_identifier}"
lifecycle {
precondition {
condition = local.platform_ref != null
error_message = "No platform with identifier '${local.platform_identifier}' is visible to this composition's meshStack API key. Check landing_zone.platform_identifier in composition_config_yaml and that the API key is allowed to list platforms."
}
}
}


resource "meshstack_building_block" "budget_alert" {
spec = {
building_block_definition_version_ref = {
uuid = local.budget_alert_definition_version_uuid
}

display_name = "Budget Alert"
target_ref = meshstack_tenant.sandbox.ref

inputs = {
budget_name = {
value_string = "Agentic Coding Budget Alert"
}
monthly_budget_amount = {
value_int = var.budget_amount
}
contact_emails = {
# just a single email for now, not a comma-separated list
value_string = var.username
}
budget_name = { value = jsonencode("Agentic Coding Budget Alert") }
monthly_budget_amount = { value = jsonencode(var.budget_amount) }
# just a single email for now, not a comma-separated list
contact_emails = { value = jsonencode(var.username) }
}
}
}


# enable spain region for the sandbox tenant because that's the only region where Anthropic's Sonnet 4 is available
resource "meshstack_buildingblock" "enable_eu_south_2_region" {
metadata = {
definition_uuid = local.enable_eu_south_2_region_definition_uuid
definition_version = local.enable_eu_south_2_region_definition_version
tenant_identifier = "${meshstack_tenant.sandbox.metadata.owned_by_workspace}.${meshstack_tenant.sandbox.metadata.owned_by_project}.${meshstack_tenant.sandbox.metadata.platform_identifier}"
}

resource "meshstack_building_block" "enable_eu_south_2_region" {
spec = {
building_block_definition_version_ref = {
uuid = local.enable_eu_south_2_region_definition_version_uuid
}

display_name = "Enable eu-south-2 region"
target_ref = meshstack_tenant.sandbox.ref

inputs = {
region = {
value_single_select = "eu-south-2"
}
region = { value = jsonencode("eu-south-2") }
}
}
}
Expand Down
26 changes: 7 additions & 19 deletions modules/aws/agentic-coding-sandbox/buildingblock/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ YAML configuration for landing zone and building blocks. Expected structure:
```yaml
landing_zone:
landing_zone_identifier: "my-landing-zone"
platform_identifier: "my-platform"
platform_identifier: "my-platform.my-location" # full platform identifier, <platform-name>.<location-name>
budget_alert_building_block:
definition_uuid: "uuid-here"
definition_version: 1
definition_version_uuid: "uuid-here" # uuid of the building block definition *version* to provision
enable_eu_south_2_region_building_block:
definition_uuid: "uuid-here"
definition_version: 1
definition_version_uuid: "uuid-here"
project:
default_tags:
environment: "sandbox"
Expand All @@ -39,23 +37,13 @@ EOF
}

validation {
condition = can(yamldecode(var.composition_config_yaml).budget_alert_building_block.definition_uuid) && yamldecode(var.composition_config_yaml).budget_alert_building_block.definition_uuid != null
error_message = "budget_alert_building_block.definition_uuid is required in composition_config_yaml"
condition = can(yamldecode(var.composition_config_yaml).budget_alert_building_block.definition_version_uuid) && yamldecode(var.composition_config_yaml).budget_alert_building_block.definition_version_uuid != null
error_message = "budget_alert_building_block.definition_version_uuid is required in composition_config_yaml"
}

validation {
condition = can(yamldecode(var.composition_config_yaml).budget_alert_building_block.definition_version) && yamldecode(var.composition_config_yaml).budget_alert_building_block.definition_version != null
error_message = "budget_alert_building_block.definition_version is required in composition_config_yaml"
}

validation {
condition = can(yamldecode(var.composition_config_yaml).enable_eu_south_2_region_building_block.definition_uuid) && yamldecode(var.composition_config_yaml).enable_eu_south_2_region_building_block.definition_uuid != null
error_message = "enable_eu_south_2_region_building_block.definition_uuid is required in composition_config_yaml"
}

validation {
condition = can(yamldecode(var.composition_config_yaml).enable_eu_south_2_region_building_block.definition_version) && yamldecode(var.composition_config_yaml).enable_eu_south_2_region_building_block.definition_version != null
error_message = "enable_eu_south_2_region_building_block.definition_version is required in composition_config_yaml"
condition = can(yamldecode(var.composition_config_yaml).enable_eu_south_2_region_building_block.definition_version_uuid) && yamldecode(var.composition_config_yaml).enable_eu_south_2_region_building_block.definition_version_uuid != null
error_message = "enable_eu_south_2_region_building_block.definition_version_uuid is required in composition_config_yaml"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ terraform {
required_providers {
meshstack = {
source = "meshcloud/meshstack"
version = ">= 0.7.1"
version = ">= 0.24.3"
}
}
}
Loading