I've already posted twice about using AI/LLMs, and buckle up for another exciting installment. But! Before I get into the meat of the topic, I need to lay some groundwork.
The company I work for uses Amazon Web Services (AWS) for compute and storage. Within AWS you're very much encouraged to set up a Virtual Private Cloud (VPC) which is a way of isolating your cloud infrastructure away from the internet and other AWS users. Part of the VPC is a firewall that prevents outside access to the Virtual Private Network. Of course, as an employee, I need to be able to get inside the firewall, so we have a VPN Gateway that allows outside users on the public internet to access resources inside the VPC, but only if you can successfully authenticate with the gateway.
Below is a diagram showing this. My laptop connects to the VPN gateway, and from the gateway I can access a Linux machine. For example, if I want to ssh into a Linux box, that connection gets wrapped via the VPN connection to the gateway, which then unwraps it and passes the ssh connection to the Linux box.
┌─────────────────────────────────────────┐
│ VPC │
│ │
┌─────────┐ │ ┌──────────────┐ ┌──────────────┐ │
│ Laptop ├──────┼►│ VPN Gateway ├──────►│ Linux Box │ │
└─────────┘ │ └──────────────┘ ssh └──────────────┘ │
VPN(ssh)└─────────────────────────────────────────┘
For reasons that are not important here, we are overhauling how we do various
things with respect to security. One part of this is we are turning off the
ability to ssh into Linux machines in favor of
AWS SSM.
SSM gives you an encrypted shell/terminal connection to a host, just like ssh, but
it doesn't use ssh at all.
One motivation is that AWS SSM allows convenient logging of who connected to
a particular machine, when they did, and what shell commands they ran.
Another is that access to resources can be defined at the
AWS permissions level, away from the individual
Linux machines.
With SSM we don't need a gateway to access things inside the VPN.
It works like this:
When the Linux box boots, an agent on the machine registers
itself with SSM, which lives outside
the VPN (it's run by AWS, not us).
Next, when I wish to connect to the box, my laptop authenticates
with SSM, which checks if I'm allowed to connect.
If I am, SSM connects me to the machine inside the VPN by forwarding data
between my laptop and the Linux box.
At the same time, logs are kept of the connection and commands I run.
See the diagram below.
┌─────────────┐ ┌─────────────┐
┌────────────►│ AWS SSM ├─►│ AWS Logs │
│ └─────────▲───┘ └─────────────┘
│ │
┌─────┴─────┐ │
│ Laptop │ ┌────────────┼───────┐
└───────────┘ │ VPC │ │
│ ┌─────────┴────┐ │
│ │ Linux Box │ │
│ └──────────────┘ │
└────────────────────┘
The official way to connect is via the
AWS CLI tool,
which is written in Python.
Somewhat oddly, the command to connect,
aws ssm start-session --target instance-id --profile somename --region us-east-1,
actually hands off to the Go binary
session-manager-plugin
after authentication is completed.
This all works, but it wasn't satisfactory.
I found it clunky and inconvenient — just compare the long aws ssm
command above to the much shorter command ssh user@host-ip!
Much of that clunky command can be scripted away,
but the official client has some broken functionality.
For example, I don't use the nano text
editor often, but it's useful for quick edits
(I also use vi, if you're wondering).
It uses "Ctrl-key" actions, such as searching ("Ctrl-w"), saving ("Ctrl-o"),
and quitting ("Ctrl-x").
There may be something wrong on my end I never diagnosed,
but I couldn't get any of those "Ctrl-key" commands to work.
Additionally, ssh has its companion program
scp
that transfers files between computers.
You can imagine that this is a useful feature, and it's something that
SSM doesn't include.
Because of this I decided to see what an LLM (Claude)
could do. I asked it to write
a program that worked with AWS SSM but acted more like ssh.
I named it sshaws.
I told it to write it in Rust because Rust is fast,
secure, and I figured that all the required crates would
already exist.
To give away the ending, the LLM did a fine job!
The program doesn't have any of the odd quirks (no "Ctrl-key" problems) that
aws ssm start-session does.
But more than that, I tailored it to work well with my workflow, and it's
now more convenient than ssh ever was, amazingly.
Here are a few examples of neat features it has:
- I had it add a Terminal User Interface (TUI) that auto discovers all the Linux boxes I have access to (see the screenshot below1). It shows if the instance is running, or if I can access the instance (perhaps the SSM agent isn't set up on the Linux machine). Other metadata can also shown, such as instance type, IP address, or environment. I can filter the instances list with a simple text search. The instance listing is especially useful for me because much of my workflow uses temporary Linux machines that exist for minutes to hours, so being able to quickly narrow down to one is great.
-
There is a "recent" hosts pane that is useful for reconnecting to a host I've worked with recently (bottom left). Instances I have connected to that have been deleted are shown with
strike through text, while those simply powered off use greyed out text. -
The application has a
configfile that allows me to define quick shortcuts for machines I access frequently. These shortcuts are available in a TUI pane (top left), and also from the command line, e.g.sshaws webhost. -
Unlike VPN/ssh connections, SSM connections can time out after as little as six hours due to AWS authentication rules. Having a session die while using it is very annoying, so I added a feature where
sshawswill auto-connect to a running tmux session, or start one if needed. This way, if you're cut off, what you were doing on the host is uninterrupted, and you can pick up where you left off by reconnecting. -
To replace
scpI had the LLM add flags to transfer files:sshaws put file.txt webhost:/home/user/orsshaws get webhost:/home/user/file.txt .. But even better, I had it add a second TUI (see below) that allows me to browse my local machine and remote, and mark files and directories for transfer either direction. It auto compresses and decompresses files and directories transparently to speed up transfers.
- I added a command
eachwhich will run a command on more than one host in parallel and return the result, for examplesshaws each 'boxname*' 'uptime'will print out the result of running the uptime command on all hosts that matchboxname*, e.g.boxname01,boxname02, andboxname-prodwould all match.
Why was the LLM so successful at this? The answer is simple: LLMs are advanced prediction engines, like Google autocomplete, but fancier. If you tell it where to start and where to go, you're giving it a path to follow, and that's when they work best. In this case I asked it to put to things together (SSM & ssh) that it knows about because it's all open source, and what functionality I wanted. It didn't have to invent anything new, it just had to mix two things together by following my instructions.
Am I okay with using LLM like this? Yes, yes I am. My job is not writing tooling for accessing AWS SSM. As I said above, nothing new is being created here; existing things were just smooshed together. My job as a human is to create new things with my biological creativity, and offloading this task to an LLM was a win.
Finally, I don't know if I will try to make sshaws open source.
There's nothing proprietary about it, so I could.
I'm not super worried about major issues.
I've passed it through
Claude Fable2,
which has been reported as being excellent at finding code bugs, and it
fixed a few minor ones.
While the tool might be useful for people outside my company,
I would feel more comfortable about releasing it if I and a few other humans
went through it and audited it for hallucinations and confusing comments,
Fable's findings notwithstanding.