Skip to content

runtime-service's Terraform module: the table, the API, the relay, the intake from EventBridge, the SBOM bucket - #64

Merged
fgurbanov merged 1 commit into
mainfrom
runtime/terraform
Sep 27, 2026
Merged

fgurbanov merged 1 commit into
mainfrom
runtime/terraform

Conversation

@fgurbanov

Copy link
Copy Markdown
Contributor

The module a tenant's root calls to deploy runtime-service (ADR-0027), modeled on work-service's.

What it makes

  • Record. The table, in the shared shape: pk/sk, gsi1, gsi2, the sparse pending index, TTL, PITR, prevent_destroy.
  • The SBOM bucket. Versioned, encrypted, never public. Pipelines put their SBOMs under sbom/<application>/; every function may only GetObject there.
  • The API. Behind the Lambda Web Adapter on an HTTP API, with RECORD_SINK=off, a 5xx alarm and the gateway's access log.
  • The relay. On a schedule under the spine's policy, with archive_prefix (e.g. runtime/), and alarms for errors, silence, and a refusal (component runtime).
  • With intake. An EventBridge rule on the default bus for maestro.build and maestro.deploy (overridable sources) feeds runtime-service's own queue, next to work-service's rule for the same deploys. Also: a DLQ with its alarm, the intake function acting as the named prn-w-… workload with ReportBatchItemFailures, and IAM for the table (no Scan), a read of the SBOMs, and the queue.
  • With signals. SIGNALS=work, WORK_API_URL, SIGNALS_TOKEN_URL and SIGNALS_CLIENT_ID on both the API and the intake, since both record deploys. SIGNALS_CLIENT_SECRET comes through secrets. Without it, SIGNALS=log.

What the tenant adds

  • Pipeline roles. Each application's pipeline role gets s3:PutObject on <bucket_arn>/sbom/<application>/*, next to its events:PutEvents.
  • Workload principals.
    • The intake's own workload, admitted with intake to runtime-service's workspace.
    • With signals, a client-credentials client whose workload is admitted with intake to work-service's workspace. Its secret goes in Secrets Manager.
  • The sealer seals the module's archive_prefix.

Also

  • .github/workflows/runtime-terraform.yml: fmt, validate, tests, the example root, and bundles that boot. The API boot was checked locally: it gets as far as the database.
  • runtime/README.md has an On AWS section; runtime-service.md's status line and its ports now name the module.
  • checkout-components.sh already builds runtime/api (lockfile ≤ 3 deep); only its comment is updated.
  • deploy.sh needed nothing: its deploy events come from the tenant's deploy-events.json.

Checks

  • terraform test: 10 passed.
  • fmt, validate, example root validate; links, boundaries and public guards ok.

🤖 Generated with Claude Code

…e intake from EventBridge, the SBOM bucket

Modeled on work-service's: the shared table shape (prevent_destroy, PITR, TTL), the API behind the
Web Adapter on an HTTP API, the relay on a schedule under the spine's policy with its own archive
prefix. runtime-service's own: a bucket for the SBOMs the pipelines put under sbom/<application>/,
which every function may only read; with `intake`, a rule on the default bus for maestro.build and
maestro.deploy into its own queue and the intake function; with `signals`, a digest mismatch sent
to work-service's intake (SIGNALS=work on the API and the intake, the client secret through
`secrets`). Ten mocked-provider tests, an example root, and a workflow that also boots the bundles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fgurbanov
fgurbanov merged commit 7f23e23 into main Sep 27, 2026
12 checks passed
@fgurbanov
fgurbanov deleted the runtime/terraform branch September 27, 2026 11:48
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.

1 participant