Skip to content

feat(compute): add AWS Lambda MicroVMs ComputeStrategy backend — P1 (#645) - #689

Draft
dreamorosi wants to merge 4 commits into
aws-samples:mainfrom
dreamorosi:feat/645-lambda-microvm-p1
Draft

feat(compute): add AWS Lambda MicroVMs ComputeStrategy backend — P1 (#645)#689
dreamorosi wants to merge 4 commits into
aws-samples:mainfrom
dreamorosi:feat/645-lambda-microvm-p1

Conversation

@dreamorosi

Copy link
Copy Markdown
Member

Implements Phase P1 of ADR-021 (#688): the lambda-microvm compute backend — strategy (start/poll/stop), CDK infrastructure, bootstrap policy, CLI support, and layered regional-availability enforcement. AgentCore remains the default. Suspend/resume is P3; agent-side hook serving and smoke parity are P2 — the ADR and the construct both warn explicitly that a P1-built image is not runnable end to end.

Strategy reports, orchestrator interprets

LambdaMicrovmComputeStrategy.pollSession maps the six-state MicrovmState enum mechanically (SessionStatus gains 'suspended'); the orchestrator cross-references DynamoDB — substrate-terminal + non-terminal status → failed (with a confirm re-read to avoid failing a successful fast teardown), suspended + non-AWAITING_APPROVAL → anomaly event, no fail-fast. RunMicrovm always omits idlePolicy (auto-suspend disabled by construction, asserted by tests) and pins maximumDurationInSeconds at 28 800 s (AgentCore 8 h parity). Strategy errors carry a MicroVM <op> failed marker so the new classifier entries cannot change agentcore/ECS retry semantics — pinned by regression tests against the pre-change UNKNOWN shape.

No image wildcards in IAM

Every grant is scoped to the exact image ARN (bare names are resolved via formatArn; a ':*' sibling covers version-qualified forms — image names cannot contain :). microvmConfig.imageArn is compiler-required, so the account-wide fallback cannot return silently. Orchestrator gets exactly RunMicrovm/GetMicrovm/TerminateMicrovm/PassNetworkConnector + scoped iam:PassRole; the cancel Lambda gets TerminateMicrovm only; no Suspend/Resume/auth-token grants anywhere (P3), asserted by tests including on the generated bootstrap JSON.

Regional availability enforced in layers

Synth-time gate on the 5 launch regions with a microvm_region_override escape hatch (token regions skipped, documented); CLI onboarding probes ListManagedMicrovmImages on the effective compute type (flag ?? stored ?? default) before any write; platform doctor probes when an active blueprint uses the backend; orchestration-time classification is non-retryable with a configuration remedy.

Cancellation ordering fix worth reviewer attention

The new lambda-microvm branch in cancel-task.ts is deliberately placed before the agentRuntimeArn fallback: RUNTIME_ARN is set stack-wide whenever AgentCore stop is wired, so a MicroVM task would otherwise have invoked StopRuntimeSession against an unrelated runtime in mixed deployments. Pinned by a regression test.

ADR-021 refined in place (proposed): six-state poll-mapping table, GetMicrovm NotFound → completed rationale, microvmId/microvmIdentifier seam, per-hook phasing table.

Verification: cdk 141 suites / 2 744 tests, cli 52 / 651, tsc + eslint clean in both, types-sync green, knip at baseline (78), bootstrap generation and docs sync deterministic. DEPLOYMENT_ROLES.md gains golden policy block [5] with test parity.

Refs #645

…ws-samples#645)

Implement Phase P1 of ADR-021: the lambda-microvm compute backend
(start/poll/stop), its CDK infrastructure, bootstrap policy, CLI
support, and regional-availability enforcement. Suspend/resume (P3)
and agent-side hook serving / smoke parity (P2) follow separately;
a P1-built image is documented as not yet runnable end to end.

Handlers (cdk/src/handlers):
- ComputeType widens to 'agentcore' | 'ecs' | 'lambda-microvm';
  SessionHandle gains {microvmId, endpoint}; SessionStatus gains
  'suspended'; resolveComputeStrategy keeps the exhaustive-never gate
- LambdaMicrovmComputeStrategy: RunMicrovm with idlePolicy omitted
  (auto-suspend disabled by construction) and
  maximumDurationInSeconds=28800 (AgentCore 8h parity); payload
  inline in runHookPayload up to exactly 16384 bytes, S3 pointer
  above; GetMicrovm poll maps the six-state MicrovmState enum
  mechanically (no task-state interpretation in the strategy);
  TerminateMicrovm best-effort with differentiated error handling;
  errors wrapped with a MicroVM marker so classifier entries cannot
  leak retry semantics onto other backends (regression-pinned)
- Orchestrator: persists {microvmId, endpoint} to compute_metadata;
  cross-references substrate state vs DynamoDB (terminal + non-
  terminal -> failed with confirm re-read; suspended + non-
  AWAITING_APPROVAL -> anomaly event, no fail-fast); finalization
  and cancellation terminate the MicroVM (cancel branch ordered
  before the AgentCore RUNTIME_ARN fallback to avoid stopping an
  unrelated runtime in mixed deployments)

Infra (cdk/src/constructs, stacks, bootstrap):
- LambdaMicrovmCompute construct: CfnMicrovmImage +
  CfnNetworkConnector L1s (platform-VPC egress, 443-only SG), build/
  execution roles trusted by lambda.amazonaws.com with
  sts:TagSession + aws:SourceAccount, execution role admitted via
  AgentSessionRole.admitComputeRole, payload bucket (1-day expiry,
  execution-role read-only, orchestrator put-only), three documented
  image-config states with mutually exclusive synth warnings
- IAM scoped to the exact image ARN (+ ':*' version hedge; image
  names cannot contain ':') — no microvm-image:* wildcard anywhere;
  orchestrator gets only RunMicrovm/GetMicrovm/TerminateMicrovm/
  PassNetworkConnector + scoped iam:PassRole; cancel Lambda gets
  TerminateMicrovm only; no Suspend/Resume/auth-token grants (P3)
- Synth-time region gate (5 launch regions) with
  microvm_region_override escape hatch; token regions skipped
- Bootstrap: conditional IaCRole-ABCA-Compute-LambdaMicrovms policy
  behind ComputeTypes (1.2.0 -> 1.3.0), deploy-time actions only;
  DEPLOYMENT_ROLES.md golden block [5] + golden-baseline parity test
- abca:compute-backend=lambda-microvm cost tags;
  scripts/package-microvm-artifact.sh for the zip+Dockerfile flow

CLI (cli/src):
- Onboarding probes availability (ListManagedMicrovmImages) on the
  EFFECTIVE compute type (flag ?? stored ?? default) before any
  write, rejecting with launch-region list + agentcore/ecs remedy
- platform doctor check when an active blueprint uses the backend
  (access-denied -> warn per checkBedrockModel precedent); runtime
  status groups the substrate like ECS

ADR-021 refined in place (proposed): six-state poll mapping table,
GetMicrovm NotFound -> completed rationale, microvmId vs
microvmIdentifier seam, per-hook phasing table and the explicit
"P1 image is not runnable end to end" consequence.

Verification: cdk 141 suites / 2744 tests; cli 52 suites / 651
tests; tsc + eslint clean in both; types-sync green; knip at
baseline (78); bootstrap generation and docs sync deterministic.

Refs aws-samples#645

Co-authored-by: Claude <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Jul 30, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@d53a882). Learn more about missing BASE report.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #689   +/-   ##
=======================================
  Coverage        ?   90.81%           
=======================================
  Files           ?      246           
  Lines           ?    61358           
  Branches        ?     6529           
=======================================
  Hits            ?    55721           
  Misses          ?     5637           
  Partials        ?        0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dreamorosi

Copy link
Copy Markdown
Member Author

I'll address the CI comments tomorrow

dreamorosi and others added 2 commits July 31, 2026 12:26
…utions

The lock regenerated while adding @aws-sdk/client-lambda-microvms did
not honor the root resolutions field, reintroducing vulnerable
brace-expansion pins (GHSA-mh99-v99m-4gvg, cleared on main in aws-samples#658)
and drifting from the resolution shape CI's install produces (yaml
dedupe to 2.9.0, strnum/xml-naming entries), which tripped the
fail-on-mutation gate.

Regenerated with Node 22.23.2 + Yarn 1.22.22 (CI-equivalent) via
yarn install --check-files: brace-expansion collapses to patched
5.0.9 everywhere, osv-scanner 2.4.0 reports no issues, second
install is byte-identical, and both workspaces stay green
(cdk 2744, cli 651; tsc clean).

Refs aws-samples#645

Co-authored-by: Claude <noreply@anthropic.com>
Close the 14 uncovered patch lines on PR aws-samples#689: platform-doctor repo
lookup failure shapes (non-Error throw, missing table output, lookup
error, empty active-repo list) and non-Error MicroVM probe
formatting; orchestrate-task reconciliation task-failure path; and
the agent stack's defensive missing-image-ARN invariant.

Tests only, no production changes; no unreachable lines found.
cli 655, cdk 2746, tsc + eslint clean in both.

Refs aws-samples#645

Co-authored-by: Claude <noreply@anthropic.com>
@dreamorosi
dreamorosi marked this pull request as ready for review July 31, 2026 18:05
@dreamorosi
dreamorosi requested review from a team as code owners July 31, 2026 18:05
The create-microvm-image call must match the Lambda MicroVMs API
model (the AWS CLI is generated from it): architecture is ARM_64 and
hooks are enable flags (run: ENABLED) with service-defined paths -
not the CFN L1's string shapes the script had copied. The construct
is intentionally unchanged: CFN fields are unconstrained strings
with their own spec conventions, validated at deploy time.

Caught while drafting the P1 verification runbook; offline tests
cannot exercise API payload shapes. bash -n clean; cdk suite green.

Refs aws-samples#645

Co-authored-by: Claude <noreply@anthropic.com>
@dreamorosi
dreamorosi marked this pull request as draft July 31, 2026 23:32

@krokoko krokoko left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this — Phase P1 of ADR-021 is thoughtfully scoped, and the write-up makes the intentional non-goals (P2 hooks / P3 suspend) easy to review against. Strategy-vs-orchestrator split, image-ARN IAM scoping, cancel ordering before the RUNTIME_ARN fallback, and the layered regional gates all look solid. CI green + strong test coverage help a lot.

Request changes

Onboard should gate on ComputeSubstrate for lambda-microvm (parity with ECS)

In cli/src/commands/repo.ts, ECS already refuses onboard when the stack wasn’t deployed with the ECS substrate. MicroVM currently only probes regional availability (ListManagedMicrovmImages), so an operator can still write compute_type=lambda-microvm against an agentcore-only stack and only fail later at RunMicrovm.

Suggest mirroring the ECS check (and the onboard note) for lambda-microvm when ComputeSubstrate is present and not lambda-microvm. The agent stack already emits that output value.

Suggestions (non-blocking / nice-to-have in this PR)

  1. microvm_suspend_anomaly spamreconcileMicrovmSubstrateState emits on every poll (~30s) while suspended outside AWAITING_APPROVAL. Rare in P1 (no Suspend grants), but once it hits it can flood events for a long window. Emitting once per task (e.g. a PollState flag) would keep “no fail-fast” without the noise — especially useful before P3.

  2. Orphan MicroVM if persist fails after RunMicrovmstart-session starts the VM, then writes compute_metadata; the catch path failTasks without TerminateMicrovm. Same race as AgentCore/ECS, but MicroVM cost/quota makes the leak more expensive. Best-effort terminate from the in-memory handle in the catch would close it. Fine as a follow-up issue if you’d rather not expand this PR.

  3. Shared payload-bucket readpayloadBucket.grantRead(executionRole) is bucket-wide (incl. list), same shape as ECS #502. Scoping to the task key / dropping List* would improve isolation when this backend is enabled; also fine as follow-up.

  4. Incomplete RunMicrovm response — the missing microvmId/endpoint throw isn’t wrapped with wrapMicrovmError, so it may miss the MicroVM classifier marker. Small consistency fix.

What looks great

  • Exact 16 384 inline/S3 payload split, idlePolicy omitted, 28800s max duration
  • Terminal substrate + DDB re-read before fail; suspend + approval treated as healthy
  • No Suspend/Resume/auth-token grants; bootstrap deploy-time only with golden policy block
  • Packaging script API shapes aligned with the service model
  • Knip unexports are fine hygiene

Happy to re-review quickly once the onboard gate lands — and open to deferring 2–3 to tracked follow-ups if you prefer to keep this PR tight.

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.

3 participants