fix(aws): migrate agentic coding sandbox to ref-based meshStack resources - #252
fix(aws): migrate agentic coding sandbox to ref-based meshStack resources#252grubmeshi wants to merge 1 commit into
Conversation
Scorecard Check
📊 meshstack-hub Module Scorecard
📋 Per-Module Category SummaryScore per category per building block.
Core Structure — some checks failingBasic module file structure and documentation — applies to 1 modules
Core Structure — Summary
Integration — not applicablemeshstack_integration.tf conventions — applies to 0 modules No applicable modules. Azure Backplane — not applicableAzure UAMI-based 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. Testing — some checks failingEnd-to-end test coverage — applies to 1 modules
Testing — Summary
|
|
This pull request is automatically being deployed by Amplify Hosting (learn more). |
5a946cc to
c0385aa
Compare
…rces meshstack_tenant runs on the meshTenant v4 API since terraform-provider-meshstack v0.24.0: metadata.platform_identifier became spec.platform_ref (a platform uuid ref) and spec.landing_zone_identifier became spec.landing_zone_ref. This module still wrote the pre-v4 body, so it did not even validate against a current provider. The composition is configured with a platform identifier, not a uuid, so a meshstack_platforms data source resolves the identifier to the platform's computed ref. A precondition turns a mistyped or invisible platform identifier into a readable error instead of a missing required attribute. The two child building blocks move from the deprecated meshstack_buildingblock (v1) to meshstack_building_block. They target the tenant through its computed ref instead of a hand-built tenant identifier string and pass jsonencoded input values. v1 was only used because the tenant uuid was unavailable, which the v4 tenant fixes. meshstack_building_block references a building block definition VERSION by uuid, so composition_config_yaml replaces each block's definition_uuid plus numeric definition_version with a single definition_version_uuid. The provider has no data source that resolves a definition or one of its versions, so that uuid has to be configured; the landing zone and the platform stay identifiers because the provider can resolve those. The operator-facing config schema therefore breaks exactly once. The provider constraint moves to >= 0.24.3, the release that added the plural platforms data source. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
c0385aa to
8ce41c2
Compare
What was broken
modules/aws/agentic-coding-sandbox/buildingblock/main.tfwas written against a meshStack provider that no longer exists. Since terraform-provider-meshstack v0.24.0meshstack_tenantruns on the meshTenant v4 API:metadata.platform_identifierbecamespec.platform_ref, a{uuid, kind}referencespec.landing_zone_identifierbecamespec.landing_zone_ref, a{name, kind}referenceSo the module did not even validate. The two child building blocks used the deprecated
meshstack_buildingblock(v1) resource and built theirmetadata.tenant_identifierfrommeshstack_tenant.sandbox.metadata.platform_identifier, an attribute that no longer exists.The tenant
platform_refneeds a platform uuid, and this composition is configured with a platform identifier, so the module resolves the uuid itself:meshstack_platformsdata source exposes a computedrefper element that goes straight intospec.platform_ref, which is the pattern the provider docs recommend.identifier(the full<platform-name>.<location-name>) rather than the server-sideidentifierfilter, because that filter matchesmetadata.name, which does not carry the location segment. Both provider doc examples match client-side too.preconditionturns a mistyped platform identifier, or one the API key cannot see, into a readable error instead of a bare "required attribute is null".modules/ske/ske-starterkit/buildingblockandmodules/aks/starterkit/buildingblocktakeplatform_refas a variable. That is the better model there: those building blocks are wired up by ameshstack_integration.tfthat already holds the platform resource. This module has no integration file and is configured purely from a YAML blob that a platform operator fills in, so it resolves the ref at runtime.The two child building blocks
Both move from
meshstack_buildingblock(v1) to the ref-basedmeshstack_building_block, the idiommodules/ske/ske-starterkit/buildingblockalready uses:ref({uuid, kind = "meshTenant"}) that drops straight intospec.target_ref, so the NOTE is gone and notenant_identifierstring is assembled from workspace, project and platform identifiers any more.value_string/value_int/value_single_selectattributes to a singlejsonencodedvalue.meshstack_building_blockdefaultswait_for_completiontotrue, so the composition now waits for each child block's run to reach a terminal state (bounded by the default 30m timeout). That is the behavior worth having here: the composition reporting success should mean the sandbox is actually usable, not that two runs were queued.The operator-facing config schema, deliberately broken once
meshstack_building_blockreferences a building block definition version by uuid, whilecomposition_config_yamlcarried adefinition_uuidplus a numericdefinition_version. No shape of that config survives, so the schema breaks in this PR either way. It breaks exactly once, and it gets smaller:The rule the config now follows: name a thing by the most human-readable key the provider can actually resolve.
definition_version_uuidper block replacing two keys. The provider has no data source that resolves a building block definition, or one of its versions, by uuid or by name:meshstack_building_block_definitionsfilters only byworkspace_identifierand issues an extra API call per definition to load its versions, and these definitions are owned by the operator's workspace, not necessarily the caller's. So the uuid has to be configured, and configuring the version uuid is the honest form of what the resource consumes.landing_zone.platform_identifierstays an identifier. Rejected: taking aplatform_uuid(or a full ref) as input. It would delete themeshstack_platformslookup and its precondition, but it would make the operator dig a uuid out of the panel for a value that is visible as an identifier everywhere in meshStack and that the provider resolves for us. "The config contains one uuid already, so it may as well contain three" is not an argument for making a readable field unreadable. The lookup and the precondition therefore stay exactly as they are.landing_zone.landing_zone_identifierstays an identifier. Rejected: turning it into a nestedlanding_zone_ref. Alanding_zone_refis{name, kind}and thenameis the identifier, so a nested YAML ref would be the same string plus ceremony, andkindis the only value it could ever have. Rejected as well: resolving it throughmeshstack_landingzones— a lookup that converts an identifier into the same identifier buys nothing.variables.tfvalidations shrink from four building-block checks to two (each block'sdefinition_version_uuidis required), the docstring example and the hand-written config example inREADME.mdmatch the new schema, and the terraform-docs section is regenerated.Consumers of this composition update their
composition_config_yamlonce when this merges. There is no compatibility shim and no deprecation window; that is deliberate, and it is why both breaking changes land together.Provider constraint
>= 0.7.1becomes>= 0.24.3:refneed>= 0.24.0meshstack_building_blockwithspec.building_block_definition_version_ref,spec.target_refandjsonencoded inputs has been available since v0.23.0, so it does not raise the floor.spec.parent_building_block_refs(renamed in v0.24.4) is not used here.meshstack_platformsdata source shipped in v0.24.3, which is the real floorv0.24.4 is not required: it only removes the deprecated
spec.quotas(never set here) and renames a building block attribute this module does not use.No state migration path
No
movedblocks and no import shims. There is no in-place move frommeshstack_buildingblock(v1) tomeshstack_building_block, and the tenant is treated as a fresh resource, so an existing sandbox is destroyed and recreated. This is deliberate: the sandboxes are short-lived, per-developer environments, and carrying a migration from the v1 bodies is not worth it.Verification
terraform fmtclean.terraform init -backend=false+terraform validatepass, with no warnings, against the registry release v0.24.3 (the declared floor), against v0.24.4 (what the constraint resolves to today), and against a local dev build of the provider. The twomeshstack_buildingblockdeprecation warnings the previous revision emitted are gone with the resource.ci/validate_modules.shreportsNumber of errors: 0.aws/agentic-coding-sandboxis unchanged; its two failing checks (nomeshstack_integration.tf, noe2e/) are pre-existing.buildingblock/README.mdregenerated with the nix-pinned terraform-docs v0.20.0 via the repo's pre-commit hooks.Where this is going
The module still has no
meshstack_integration.tf, which is the one Core Structure check the hubscorecard fails for it. Its building block definition, and those of the two children it composes
(
aws/budget-alert,aws/opt-in-region), were created by hand in the panel. That is why the ICFconsumer has to paste definition uuids into its configuration.
Agreed plan for this PR:
meshstack_integration.tftoaws/agentic-coding-sandbox,aws/budget-alertandaws/opt-in-region.composition_config_yamlin favour of typed variables, following the ske starterkit:platform_ref,landing_zone_ref, andbuilding_block_definitionsas a map of{uuid, version_ref}wired from the two child modules' outputs. This deletesdefinition_version_uuid, introduced earlier on this branch, before anyone consumes it.platform_identifiervariable on the integration file and resolve it to a refthere with the
meshstack_platformsdata source, so no consumer writes a platform uuid and thelookup runs once at definition apply time instead of on every building block run.
buildingblock/APP_TEAM_README.mdinto the definition's inlinespec.readme, asAGENTS.mdrequires for modules with an integration file.On the consumer side, ICF gets a local Terraform root next to its
terragrunt.hclthat instantiatesthe three hub modules, holds the three
importblocks that adopt the existing productiondefinitions, and pins
bbd_draft = falselike the neighbouring AWS building blocks. Existingbuilding blocks keep running, because they stay on the definition version they were created with.
Validation is plan-only against production until the plan shows the three imports and nothing
unintended.
Blocked on
Sufficient permissions on meshcloud-prod: an AWS profile for account
122242464811and meshStack APIcredentials for
https://federation.prod.meshcloud.io. Without them the definitions cannot beimported, and two facts stay unknown: how many sandboxes are live on the current definition, and
which workspace owns it (
meshsreowns every other as-code AWS definition in that foundation, so itis the likely answer).