13 · Cloud provider launch
The "spin a real cloud VM, install nymph, register" flow. The most complex path: cloud API call, secret decryption, bootstrap script, binary download, and daemon registration on a fresh image.
Exercises
- The server-side launchers —
EC2,GCE, andKube(the only three the launch routes support;SSHandSLURMreturn 422). - Secret resolution at launch time:
{ "$secret": "…" }markers in provider kwargs decrypted in the handler and never serialized back. POST /v1/namespaces/:ns/daemons/launchrendering the nymph bootstrap and handing it to the launcher as userdata / startup script.- Outbound-only registration from a fresh instance.
Requires
- Cloud credentials stored as a Lakeshore secret — kind
aws_keypair(plaintext formatted<access_key_id>:<secret_access_key>) orgcp_sa_json. - A provider registered with those credentials referenced by
{ "$secret": … }. - IAM / project permission to create, describe, and terminate instances.
- Outbound HTTPS from the instance's network, so nymph can reach the control plane and R2.
LAKESHORE_PUBLIC_URLset on the control plane. The bootstrap script bakes in the URL fromLAKESHORE_PUBLIC_URL, thenLAKESHORE_SERVER_URL, thenLAKESHORE_URL, thenhttp://localhost:$PORT— and a daemon on EC2 pointed at localhost never registers.
Verifies
Cloud provisioning end to end. When green, you can stand up ephemeral workers on demand.
Run
With --count > 1 the --name becomes a prefix (gpu-00, gpu-01, …)
and launches run at --concurrency (default 5, sized for the AWS
RunInstances rate limit, with retry on throttle). Omitting --name
falls back to <provider>-<short-ulid>.
daemon launch also reads project defaults from .lakeshore /
.lakeshore.local, walking up from cwd and stopping at the git root.
--no-config skips that discovery; --no-setup clears every setup
script from both sources.
Then confirm:
Expected output
A Worker row appears in daemon list — first pending or
setting_up, then joining once /hello lands, then active on its
first poll. providers instances shows the instance transitioning
starting → running.
Tearing it down
daemon kill terminates the cloud instance unless you pass
--no-terminate. Getting this backwards costs either money or data.
If it fails
| Symptom | Likely cause |
|---|---|
502 with awsCode: UnauthorizedOperation | IAM. The role needs ec2:RunInstances, ec2:Describe*, ec2:CreateTags, ec2:TerminateInstances, plus iam:PassRole when attaching an instance profile. |
422 only EC2, GCE and Kube supported | The provider's launcher is SSH or SLURM. |
EC2 launch requires image_id | No image_id / ami in the merged provider + mode kwargs. There is no default AMI. |
| Instance created, never registers | The bootstrap script failed, or it points at the wrong control plane. Check /var/log/cloud-init-output.log on the host and confirm LAKESHORE_PUBLIC_URL. |
secret '<name>' not found in namespace | Secrets resolve in the provider's own namespace, which is not necessarily the one you called from. Providers are org-shared; secrets are not. |
| Launches succeed until they suddenly do not | A cloud account instance-count quota. Different problem. |
Status
Manual. Costs real money — do not loop on failure.