* docs(social): EC2 Instance Connect SSH launch copy + terminal demo visual PR #1533 (feat/terminal: remote path via aws ec2-instance-connect + pty) Issue #1547 (social: launch thread for EC2 Instance Connect SSH) Content: - docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/social-copy.md 5-post X thread + LinkedIn single post, dark theme brand voice - docs/assets/blog/2026-04-22-ec2-instance-connect-ssh/ec2-terminal-demo.png (1200x800) Canvas Terminal tab mockup showing EC2 bash prompt via EIC Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(tutorial): EC2 Instance Connect SSH — workspace terminal via EIC Endpoint Runnable tutorial for PR #1533: - How EIC SSH bridges PTY to Canvas Terminal tab - Prerequisites: IAM policy, EIC Endpoint, aws-cli in tenant image - 6-step runnable snippet (workspace create → poll → Terminal verify → CloudWatch audit) - Design notes: subprocess aws-cli pattern, bidirectional context cancel - Teardown, links to social copy and infra runbook Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Molecule AI Social Media Brand <social-media-brand@agents.moleculesai.app> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Molecule AI DevRel Engineer <devrel-engineer@agents.moleculesai.app>
4.8 KiB
SSH into Cloud Agent Workspaces via EC2 Instance Connect
EC2 Instance Connect Endpoint lets you open a shell in a CP-provisioned workspace — no SSH keys, no IP hunting, no security group configuration. The platform handles the EIC call under the hood; you just click Terminal.
SSH access to a cloud agent workspace sounds like it should be simple. The instance exists in your AWS account, you have the instance_id — surely there's a direct path. There isn't, by default. Instance IPs change on restart, security groups need per-account rules, and long-lived SSH keys are a provenance problem the moment more than one person needs access.
AWS EC2 Instance Connect (EIC) Endpoint solves all of this. Instead of managing keys yourself, you delegate to AWS — the platform calls aws ec2-instance-connect ssh on your behalf, AWS pushes a short-lived key through the EIC Endpoint, and a PTY bridges straight into the Canvas Terminal tab. The access is attributable (EIC logs which principal opened the tunnel), temporary (key expires automatically), and requires no inbound security group rules (the tunnel opens outbound from the instance).
Prerequisites: CP-managed workspace in your AWS account (provisioned with
controlplanebackend andMOLECULE_ORG_IDset). Your IAM role must haveec2-instance-connect:SendSSHPublicKey+ec2-instance-connect:OpenTunnel(conditionRole=workspace). An EIC Endpoint must exist in the workspace VPC. Seedocs/infra/workspace-terminal.mdfor the one-time infra setup.
How it works
Canvas (browser) ──WebSocket──► Platform (Go)
│
▼ spawns
aws ec2-instance-connect ssh \
--connection-type eice \
--instance-id <instance_id> \
--os-user ec2-user \
-- docker exec -it <container_id> /bin/bash
│
▼
EIC Endpoint ──► EC2 Instance (PTY bridge)
The platform stores the instance_id returned by AWS during provisioning (PR #1531). When you click Terminal, the Go handler looks up the instance, calls aws ec2-instance-connect ssh, and bridges the PTY to the Canvas WebSocket.
Run it
# 1. Create a CP-managed workspace (requires controlplane backend + MOLECULE_ORG_ID)
WS=$(curl -s -X POST https://acme.moleculesai.app/workspaces \
-H "Authorization: Bearer $ORG_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "prod-agent", "runtime": "hermes", "tier": 2}' \
| jq -r '.id')
# 2. Wait for it to be running (~20-40s)
until curl -s https://acme.moleculesai.app/workspaces/$WS \
| jq -r '.status' | grep -q ready; do sleep 5; done
echo "Workspace $WS is ready"
# 3. In Canvas: open the workspace → Terminal tab
# The platform calls EIC on your behalf and opens a shell.
# No SSH keys, no IP lookup — it just works.
# 4. Verify the PTY works by running a command
whoami # should return: root (inside the container)
df -h / # disk usage inside the workspace container
echo $MOLECULE_WS_ID # confirm you're in the right workspace
# 5. Inspect the EIC tunnel via CloudWatch (AWS console)
# Filter: eventName=OpenTunnel, eventSource=ec2-instance-connect
# Principal: your IAM role ARN
# Target: the instance_id of the workspace
What you need on the AWS side
| Requirement | Details |
|---|---|
| IAM policy | ec2-instance-connect:SendSSHPublicKey + ec2-instance-connect:OpenTunnel on * with condition aws:ResourceTag/Role=workspace |
| EIC Endpoint | One per workspace VPC, reachable from the platform |
| AWS CLI | aws-cli + openssh-client installed in the tenant image (alpine: apk add openssh-client aws-cli) |
| Instance | Must be Nitro-based (T3, M5, C5, etc. — virtually all modern instance types) |
Design notes
- The EIC call is a subprocess (
aws ec2-instance-connect ssh) rather than a native SDK call. EIC Endpoint uses a signed WebSocket with specific framing thataws-cli v2implements correctly. Reimplementing it in Go is ~500 lines of crypto + protocol work. sshCommandFactoryis a var (injectable) so tests can stub the command without spawning real aws-cli processes.- Context cancellation is bidirectional: WS close kills the SSH process; SSH exit closes the WebSocket cleanly.
- If Terminal shows "EIC wiring incomplete," the EIC Endpoint or IAM policy isn't set up yet — see
docs/infra/workspace-terminal.md.
Teardown
Close the Terminal tab in Canvas, or the process exits automatically when the browser disconnects. No manual teardown needed.
EC2 Instance Connect SSH shipped in PRs #1531 + #1533. For the social launch copy, see docs/marketing/social/2026-04-22-ec2-instance-connect-ssh/.