awsx2
A fast AWS management CLI and interactive TUI built in Rust. Manages EC2 instances, SSM tunnels, and local reverse proxies through a single tool.
awsx2 # launch interactive TUI
awsx2 list # CLI mode — list all instances
Features
- Dual-mode — full-screen TUI for interactive use, CLI for scripts and automation
- EC2 management — list, start, stop, force-stop, switch instance types (GPU/CPU)
- Smart tunneling — SSM port-forwarding with ALB-aware routing, security group analysis, and bastion fallback
- Reverse proxy — auto-configures nginx +
/etc/hostsso internal URLs work directly in the browser - Cross-platform — macOS (Homebrew) and Linux (Debian/Ubuntu, RHEL/CentOS, Amazon Linux)
Prerequisites
- AWS CLI v2 with SSO configured
- Session Manager Plugin
- SSM Agent running on target EC2 instances
- nginx (only for
--proxyfeature)
Installation
CLI Usage
Run awsx2 <command>. Instance commands accept --name or read from the INSTANCE_NAME environment variable.
Instance Management
Authentication
DNS Resolution
Traces the full path: hostname → DNS → ALB → target group → EC2/Fargate backend.
Tunnels
Direct tunnel to an EC2 instance by name pattern:
# ^pattern ^local ^remote
URL tunnel with smart ALB resolution (auto-detects bastion and remote port):
The resolution chain: URL → ALB match → healthy target group → security group rules → SSM-online hop instance. Falls back to trying all available bastions if ALB resolution fails.
URL tunnel with reverse proxy so the URL works directly in the browser:
This additionally:
- Writes an nginx config forwarding port 80 → localhost:8080
- Adds
127.0.0.1 app.internal.example.comto/etc/hosts - Reloads nginx and flushes DNS cache
DNS tunnel (resolve hostname, tunnel to the resolved IP):
Remote tunnel via a specific bastion to an arbitrary host:
# ^bastion ^target ^local ^remote
Tunnel management:
TUI
Launch with awsx2 (no arguments). Navigate with keyboard — no mouse required.
Global Keys
| Key | Action |
|---|---|
Tab / Shift+Tab |
Switch tabs |
? |
Toggle help overlay |
q / Ctrl+c |
Quit |
Instances Tab
| Key | Action |
|---|---|
j / k / Up / Down |
Navigate |
g / G |
Jump to first / last |
/ |
Filter by name, ID, or type |
Esc |
Clear filter |
s |
Start instance |
S |
Stop instance |
f |
Force-stop instance |
r |
Refresh |
Columns: Instance ID, Name, Type, State, SSM Status, Tunnel, Private IP. States are color-coded: green = running, red = stopped, yellow = pending/stopping.
Tunnels Tab
| Key | Action |
|---|---|
j / k / Up / Down |
Navigate |
n |
New tunnel by instance name (wizard) |
u |
New tunnel by URL (smart ALB resolution) |
b |
New tunnel via bastion (wizard) |
d / Delete |
Stop selected tunnel |
A |
Stop all tunnels |
r |
Refresh |
Each tunnel shows real-time status with latency measurement:
● OK 42ms— tunnel active, measured round-trip▲ OPEN— port open, not yet probed◌ DOWN— tunnel unreachable
Tunnels auto-refresh every ~15 seconds.
Tools Tab
| Key | Action |
|---|---|
j / k / Up / Down |
Navigate menu |
Enter |
Execute |
Available tools:
- Switch Profile — select from
~/.aws/configprofiles - Switch Region — change AWS region
- Login — SSO login
- Resolve URL — trace DNS to backend resource
- Test Port — check if a tunnel port is open
- Stop All Tunnels — kill all SSM sessions
Reverse Proxy
The --proxy flag on tunnel-url sets up nginx so the original hostname works in your browser over the SSM tunnel.
How It Works
- Writes a site config to nginx (
proxy_passto the tunnel's local port) - Adds a
/etc/hostsentry pointing the hostname to127.0.0.1 - Reloads nginx and flushes the DNS cache
awsx2 tunnel-stopcleans everything up automatically
Platform Support
| macOS (Homebrew) | Linux (Debian/Ubuntu) | Linux (RHEL/CentOS) | |
|---|---|---|---|
| Config path | /opt/homebrew/etc/nginx/servers/ |
sites-available/ + symlink to sites-enabled/ |
/etc/nginx/conf.d/ |
| Nginx reload | nginx -s reload |
systemctl reload nginx |
systemctl reload nginx |
| DNS flush | dscacheutil + mDNSResponder |
resolvectl / systemd-resolve |
resolvectl / nscd |
nginx Installation
# macOS
# Debian / Ubuntu
# RHEL / CentOS / Amazon Linux
Architecture
awsx2
├── main.rs # Entry point, CLI (clap) + TUI event loop
├── aws.rs # AWS CLI wrapper (EC2, SSM, ALB, SG, DNS)
├── tunnel.rs # SSM tunnel lifecycle (start, detect, stop, probe)
├── proxy.rs # nginx reverse proxy + /etc/hosts management
├── models.rs # Domain types (Instance, TunnelProcess, etc.)
├── error.rs # Error types (AppError enum with thiserror)
└── tui/
├── app.rs # Application state, background task channels
├── ui.rs # Layout, colors, popup rendering
└── pages/
├── instances.rs # Instances tab (table + key handlers)
├── tunnels.rs # Tunnels tab (table + creation wizards)
└── tools.rs # Tools tab (menu + actions)
Key design decisions:
- Shells out to
awsCLI rather than using the AWS SDK — leverages existing SSO/credential configuration with zero extra setup - Tunnels are detached child processes, discovered by parsing
psoutput forsession-manager-plugin - TUI runs background operations on threads, communicates via
mpscchannels - No runtime dependencies beyond the AWS CLI and session manager plugin
Dependencies
| Crate | Purpose |
|---|---|
ratatui |
Terminal UI framework |
crossterm |
Terminal I/O (raw mode, key events) |
clap |
CLI argument parsing with env var support |
serde + serde_json |
AWS CLI JSON output parsing |
thiserror |
Error type derivation |
libc |
Unix signal handling (SIGTERM for tunnel cleanup) |
Environment Variables
| Variable | Used by |
|---|---|
AWS_PROFILE |
Default profile for all AWS operations |
AWS_DEFAULT_REGION |
Default region |
INSTANCE_NAME |
Default instance name for CLI commands |
License
MIT