Runbook: multi-cloud — AWS and GCP beside Azure, all live-verified¶
Goal¶
The deployment stage set (④–⑥) targets AWS and GCP with the same
consent-gated, spec-driven pipeline Azure has, and all three providers are
proven against real (free/cheap) tenants — including finally executing the
Azure path live, which is currently blocked only on az login.
Current state (verified)¶
- Azure is real:
AzureClientPort(application/interfaces/azure.py:44), ARM renderer (infrastructure/azure/arm.py),AzCliClientAdapter(infrastructure/azure/az_cli.py) with digest-bound consent re-verified at the mutation boundary;vibey worker --azure {memory|az}with anaz account showpreflight. Live execution has never run — needs login. - The domain deployment model (
DeploymentSpec,AzureTargetScope,DeploymentConsent,scope_digest()) is Azure-named but structurally vendor-neutral: tenant/subscription/resource-group/region map cleanly to account/project/region.
Design¶
- Generalize the port, keep the wire adapters vendor-specific.
Rename-by-addition (never break the protected system test):
CloudClientPortProtocol withdiscover_environment,execute_plan,get_resource_status,delete_resource;AzureClientPortremains as an alias.TargetScopegrows aprovider: Literal["azure","aws","gcp"]discriminant with provider-shaped scope fields;scope_digest()covers the provider so consent can never cross clouds. - AWS adapter (
infrastructure/aws/): renderDeploymentSpec→ CloudFormation template (container topology → ECS on Fargate + ALB when ingress enabled; scale frominstances); execute over theawsCLI (aws cloudformation deploy,describe-stacks) with the sameCommandExecutorseam and consent checks as az_cli.py. Preflight:aws sts get-caller-identity. - GCP adapter (
infrastructure/gcp/): container topology → Cloud Run (gcloud run deployreturns JSON; status viagcloud run services describe); no template indirection needed — Cloud Run is already declarative. Preflight:gcloud auth print-access-token. - CLI:
vibey worker --cloud {memory|az|aws|gcp}(deprecating--azurewith an alias); deploy interview gains a provider question whose default staysazure. - Live verification harness:
tests/live/test_cloud_live.py, one parametrized case per provider, each gated on its own env (VIBEY_AZURE_LIVE,VIBEY_AWS_LIVE,VIBEY_GCP_LIVE): deploy the hello-world container, poll status to Succeeded/healthy, then consent-gated delete. Cost ceiling: smallest SKUs, teardown infinally, budget alarm on each tenant.
Work items¶
- CloudClientPort + provider-discriminated scope + digest coverage + parity tests (Azure alias proven byte-compatible).
- AWS CloudFormation renderer + fixture tests.
- AWS CLI adapter + consent + fixtures at the subprocess boundary.
- GCP Cloud Run adapter + consent + fixtures.
- CLI
--cloud+ preflights + bootstrap wiring. - Deploy interview provider question + spec provider fields.
- Live tests ×3 + teardown proof.
- Docs:
docs/guides/deploying.mdgains AWS/GCP sections.
Verification¶
Fixture gates green; then three live runs, each producing a real resource ID, a Succeeded status poll, and a verified teardown (post-delete discovery shows no residue). Azure live counts as part of this workstream.
Needs from operator¶
az loginon this machine + a subscription id.- AWS: free-tier account, IAM user with scoped policy,
aws configure. - GCP: free-tier project,
gcloud auth login+ billing enabled (Cloud Run free tier covers the hello-world).
Risks¶
- Consent replay across providers — killed by provider-in-digest.
- Cloud CLIs drift (04 watches their changelogs).
- Free-tier quotas: keep live tests serialized, one resource at a time.