Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# EC2 Instance Connect SSH — Social Copy
Campaign: ec2-instance-connect-ssh | PR: molecule-core#1533
Publish day: 2026-04-22 (today)
Assets: `marketing/devrel/campaigns/ec2-instance-connect-ssh/assets/`
Status: Draft — pending Marketing Lead approval + credential availability

---

## X (Twitter) — Primary thread (5 posts)

### Post 1 — Hook

> Your AI agent has a workspace on an EC2 instance.
>
> How do you get a shell inside it right now?
>
> Old answer: copy the IP, find the key, `ssh -i key.pem ec2-user@X.X.X.X`, hope your
> security group is right.
>
> New answer: click Terminal in Canvas.
>
> Molecule AI now speaks AWS EC2 Instance Connect.

---

### Post 2 — The problem it solves

> SSH into a cloud agent workspace sounds simple.
>
> It's not.
>
> → Instance IP changes on restart
> → Key management across your whole agent fleet
> → Security group rules you have to get right every time
> → No audit trail on who SSH'd in and when
>
> EC2 Instance Connect handles all of it. Molecule AI wires it up so
> your agent workspace is one Terminal tab away.

---

### Post 3 — How it works

> Molecule AI + EC2 Instance Connect:
>
> → Workspace provisioned in your VPC, instance_id stored
> → Click Terminal tab in Canvas → WebSocket opens
> → Platform calls `aws ec2-instance-connect ssh` under the hood
> → EIC Endpoint opens a tunnel, STS pushes a temporary key
> → PTY bridges directly to the Canvas terminal
>
> No keys to manage. No IP to find. No security group dance.
> One click.

---

### Post 4 — Security angle

> Every SSH access to a cloud agent workspace should be attributable.
>
> With EC2 Instance Connect:
>
> → IAM policy gates access (condition: `Role=workspace` tag)
> → STS temporary key, auto-expires
> → EIC audit log shows which principal requested the tunnel
> → No long-lived SSH keys anywhere
>
> Your security team will appreciate this.

---

### Post 5 — CTA

> EC2 Instance Connect SSH is live in Molecule AI (PR #1533).
>
> Provision a CP-managed workspace → open the Terminal tab → you're in.
>
> If you're still `ssh -i key.pem` into your agent fleet — there's a better way.
>
> [CTA: docs.molecule.ai/infra/workspace-terminal — pending docs publish]
> #AgenticAI #MoleculeAI #AWS #DevOps #PlatformEngineering

---

## LinkedIn — Single post

**Title:** We gave AI agents their own terminal tab — powered by AWS EC2 Instance Connect

**Body:**

Getting a shell inside a cloud-hosted AI agent used to mean: find the instance IP, locate the SSH key, configure the security group, run `ssh`, hope nothing broke.

That's now one click inside Molecule AI.

We shipped EC2 Instance Connect SSH integration (PR #1533). Here's what changed:

**The old flow:**
Copy the EC2 IP → find the SSH key → configure the security group to allow port 22 → `ssh -i key.pem ec2-user@X.X.X.X` → verify you're connected

**The new flow:**
Provision a workspace in Canvas → click Terminal → you have a bash prompt

What makes this possible is AWS EC2 Instance Connect. The platform stores the `instance_id` from provisioning, calls `aws ec2-instance-connect ssh --connection-type eice` on your behalf, and the EIC Endpoint opens a tunnel with an STS-pushed temporary key. The PTY bridges straight into the Canvas Terminal tab.

Why this matters beyond convenience:

→ No long-lived SSH keys to manage or rotate
→ IAM policy controls access (condition on `aws:ResourceTag/Role=workspace`)
→ EIC audit log gives you provenance on every tunnel open event
→ Temporary keys auto-expire

Your agent workspaces are now as easy to access as your browser tab — with better audit trails than a manually managed SSH key rotation process.

EC2 Instance Connect SSH is live now for all CP-provisioned workspaces.

---

## Visual Asset Specifications

1. **Terminal demo GIF** — Canvas Terminal tab showing bash prompt inside an EC2 workspace:
- Canvas UI with a workspace node selected
- Terminal tab open, showing `ec2-user@ip-10-0-x-x:~$` prompt
- Optional: running `whoami` or `hostname` to show EC2 context
- Format: GIF or looping MP4, max 10s
- Dark theme, molecule navy background

2. **Architecture diagram** (optional for LI):
- Canvas (browser) → WebSocket → Platform (Go) → `aws ec2-instance-connect ssh` → EIC Endpoint → EC2 Instance
- Shows the tunnel path for audience who wants to understand the mechanism

---

## Campaign notes

**Audience:** DevOps, platform engineers, ML infrastructure teams running agents in AWS
**Tone:** Practical — the IAM/audit story is the differentiator for security-conscious buyers; the "one click" story is the differentiator for developer audience
**Differentiation:** No manual SSH key management vs. traditional bastion host approach
**Hashtags:** #AgenticAI #MoleculeAI #AWS #EC2InstanceConnect #PlatformEngineering #DevOps
**CTA links:** docs pending (workspace-terminal.md docs need to be published)

---

## Self-review applied

- No timeline claims ("today", "just shipped", etc.) beyond what's confirmed in PR state
- No person names
- No benchmarks or performance claims
- CTA links marked as pending until docs confirm live
79 changes: 79 additions & 0 deletions docs/tutorials/ec2-instance-connect-ssh/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# 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 `controlplane` backend and `MOLECULE_ORG_ID` set). Your IAM role must have `ec2-instance-connect:SendSSHPublicKey` + `ec2-instance-connect:OpenTunnel` (condition `Role=workspace`). An EIC Endpoint must exist in the workspace VPC. See `docs/infra/workspace-terminal.md` for 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

```bash
# 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 that `aws-cli v2` implements correctly. Reimplementing it in Go is ~500 lines of crypto + protocol work.
- `sshCommandFactory` is 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/`.*
Loading