An interactive terminal UI for launching AWS Systems Manager (SSM) sessions onto EC2 instances — no SSH keys, no bastion hosts, no copying instance IDs around.
Built with Bubble Tea and Lip Gloss.
- Profile picker — if
AWS_PROFILEisn't set, choose from the profiles in~/.aws/config(with type-to-filter), or type any profile name - Automatic SSO login — if your credentials are expired, it runs
aws sso loginfor you before continuing - Instance picker — lists running EC2 instances in the region with name, instance ID, and type; full-text filtering as you type
- Direct connect — pass an instance name, instance ID, or alias as an argument to skip the picker
- Session reason — optionally record a reason for the session, which is attached to the
StartSessionAPI call and visible in CloudTrail - Aliases — define shorthand names for frequently used instances
- AWS CLI v2
- Session Manager plugin for the AWS CLI
- AWS profiles configured in
~/.aws/config - Target instances must have the SSM agent running and an instance profile permitting Session Manager
Download a prebuilt binary for your platform from the latest release, extract it, and put aws-ssm-picker somewhere on your PATH.
Or install with Go:
go install github.com/gostega/aws-ssm-picker@latestOr build from source:
git clone https://github.com/gostega/aws-ssm-picker.git
cd aws-ssm-picker
make # vet + build, stamped with the version from `git describe`
make install # into $GOBIN, then prints the installed versionBuilding via make stamps the version and commit into the binary; a plain
go build leaves it as dev.
# Interactive: pick a profile, then pick an instance
aws-ssm-picker
# Use a specific profile and region
AWS_PROFILE=my-profile AWS_REGION=us-east-1 aws-ssm-picker
# Connect straight to an instance by name, ID, or alias
aws-ssm-picker my-web-server
aws-ssm-picker i-0123456789abcdef0
aws-ssm-picker web
# Print the build version and exit
aws-ssm-picker --versionThe version also appears in the TUI title bar on every screen.
If AWS_REGION is not set, the region is resolved from the selected profile's configuration.
After choosing an instance you're prompted for an optional reason (press Enter to skip); it's recorded in CloudTrail against the session. The tool then execs aws ssm start-session, so your terminal becomes the session directly.
Create ~/.aws_ssm_aliases with one entry per line:
ALIASES[web]="my-web-server"
ALIASES[db]="i-0123456789abcdef0"An alias maps a shorthand to either an instance name or an instance ID. The format is intentionally bash-compatible so the same file can be sourced from shell scripts.
This tool replaced a pair of bash functions in ~/.bashrc — an ssm wrapper
and a hard-coded GetId name→instance-ID lookup table. Instance IDs below are
redacted; the shape is verbatim.
GetId() {
1>&2 echo "Entering GetId"
case "$1" in
gpl10)
echo "i-xxxxxxxxxxxxxxxxx"
;;
gpl9)
echo "i-xxxxxxxxxxxxxxxxx"
;;
# ... gpl8, gpl7, gpl6, gpl5, gpl4, gpl3, gpl2, gpl1
salt)
echo "i-xxxxxxxxxxxxxxxxx"
;;
reporting)
echo "i-xxxxxxxxxxxxxxxxx"
;;
cron)
echo "i-xxxxxxxxxxxxxxxxx"
;;
logs)
echo "i-xxxxxxxxxxxxxxxxx"
;;
metabase)
echo "i-xxxxxxxxxxxxxxxxx"
;;
bastion)
echo "i-xxxxxxxxxxxxxxxxx"
;;
*)
echo "not found"
return 1
;;
esac
}
ssm () {
[[ -n "$1" ]] || read -r -p "Enter target (e.g. 'gpl2' or 'salt'): " target
read -r -p "Enter reason (ideally including jira ticket like PAY-1234): " reason
instanceid="$(GetId "$target")"
echo "You entered target $target which translates to $instanceid, and reason '$reason'"
echo "Connecting now..."
command="aws ssm start-session --target '${instanceid:?}' --reason '${reason:?}'"
echo "Running command: $command"
read -r -p "Press y to continue (y/n): " continue
[[ "${continue}" == "y" ]] && eval "$command"
}What the Go tool changed:
- Instance list comes from
ec2 describe-instancesinstead of a hand-maintainedcaseblock, so new instances need no edit — and~/.aws_ssm_aliasescovers the shorthand names that were the table's real purpose. - Profile and region are picked interactively rather than inherited from whatever was last exported.
execs the AWS CLI directly instead ofeval-ing a string, and the reason prompt is optional rather than mandatory.