awsx2 0.1.0

AWS management CLI and interactive TUI — EC2 lifecycle, SSM tunnels, ALB-aware routing, and nginx reverse proxy
awsx2-0.1.0 is not a library.

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/hosts so internal URLs work directly in the browser
  • Cross-platform — macOS (Homebrew) and Linux (Debian/Ubuntu, RHEL/CentOS, Amazon Linux)

Prerequisites

Installation

cargo build --release
cp target/release/awsx2 /usr/local/bin/

CLI Usage

Run awsx2 <command>. Instance commands accept --name or read from the INSTANCE_NAME environment variable.

Instance Management

awsx2 list                          # List all EC2 instances
awsx2 status --name my-server       # Show instance details
awsx2 start --name my-server        # Start an instance
awsx2 stop --name my-server         # Graceful stop
awsx2 force-stop --name my-server   # Force stop (immediate)
awsx2 switch gpu --name my-server   # Switch to g4dn.4xlarge
awsx2 switch cpu --name my-server   # Switch to m6i.2xlarge

Authentication

awsx2 login                # SSO login using $AWS_PROFILE
awsx2 login my-profile     # SSO login with explicit profile

DNS Resolution

awsx2 resolve https://app.internal.example.com

Traces the full path: hostname → DNS → ALB → target group → EC2/Fargate backend.

Tunnels

Direct tunnel to an EC2 instance by name pattern:

awsx2 tunnel web-server 8080 8000
#              ^pattern  ^local ^remote

URL tunnel with smart ALB resolution (auto-detects bastion and remote port):

awsx2 tunnel-url https://app.internal.example.com 8080

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:

awsx2 tunnel-url https://app.internal.example.com 8080 --proxy

This additionally:

  1. Writes an nginx config forwarding port 80 → localhost:8080
  2. Adds 127.0.0.1 app.internal.example.com to /etc/hosts
  3. Reloads nginx and flushes DNS cache

DNS tunnel (resolve hostname, tunnel to the resolved IP):

awsx2 tunnel-dns https://app.internal.example.com 8080 8501

Remote tunnel via a specific bastion to an arbitrary host:

awsx2 tunnel-remote bastion 10.0.1.42 8080 8501
#                   ^bastion ^target   ^local ^remote

Tunnel management:

awsx2 tunnel-test 8080    # Check if port is open
awsx2 tunnel-stop         # Kill all SSM tunnels + clean up proxies

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/config profiles
  • 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

  1. Writes a site config to nginx (proxy_pass to the tunnel's local port)
  2. Adds a /etc/hosts entry pointing the hostname to 127.0.0.1
  3. Reloads nginx and flushes the DNS cache
  4. awsx2 tunnel-stop cleans 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
brew install nginx

# Debian / Ubuntu
sudo apt install nginx

# RHEL / CentOS / Amazon Linux
sudo yum install nginx

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 aws CLI rather than using the AWS SDK — leverages existing SSO/credential configuration with zero extra setup
  • Tunnels are detached child processes, discovered by parsing ps output for session-manager-plugin
  • TUI runs background operations on threads, communicates via mpsc channels
  • 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