Another quick post.
What feels like a lifetime ago, I wrote a post about finding ec2
instances by name. I honestly use that script just about every day, mostly for automatically finding instances to SSH to (a la SSH config tricks). But there are a few other quick things I’ve done with it:
ec2-script
- Run a script on all instances of a given nameec2-disk
- A specialization ofec2-script
to check main disk usageterminate
- A script that I use withec2
to terminate instances from the command lineec2-cycle
- Slow cycle a given set ofec2
instances by terminating so many per minute
All of which are included in my dotfiles.
ec2-script
Run a command on every instance returned by ec2
:
#!/usr/bin/env fish
for ip in (ec2 $argv[1] --ips)
echo $ip
ssh ubuntu@$ip $argv[2..-1]
echo
end
Mostly, this is a loop I write all the time, so it’s easier to wrap it in a script. I really do like fish scripting compared to bash. Slightly easier loops, more reasonable subshell syntax, and array slicing with better quoted argument behavior. Nice.
You can do some pretty powerful things with this:
$ ec2-script app-server 'sudo docker exec -dt `sudo docker ps | awk \'/app/ { print $1 }\'` python scripts/do-stuff.py'
For each instance, look at the running docker containers, get the one named app
, and run a Python command in that container.
ec2-disk
Another specialization of the above:
#!/usr/bin/env fish
ec2-script $argv[1] 'df -h | egrep /$'
This is a one liner that will find the disk usage specifically of the root disk (the one who’s line ends with /
).
terminate
This doesn’t directly use ec2
, but I almost always call it as terminate (ec2 some-service --ip)
, so it might as well be:
#!/usr/bin/env fish
for ip in $argv
set -lx instance_data (aws ec2 describe-instances --filters Name=private-ip-address,Values=$ip)
set -lx instance_id (echo $instance_data | jq .Reservations[].Instances[].InstanceId | tr -d '"')
if test "$instance_id" = ""
echo "No instance found"
else
set -lx prompt "Terminate: $instance_id (name = "(echo $instance_data | jq -c '.Reservations[0].Instances[0].Tags[] | select(.Key == "Name") | .Value' | tr -d '"')") ? [y/N] "
read -lp 'echo "$prompt"' confirm
switch $confirm
case Y y
echo "Terminating $instance_id"
aws ec2 terminate-instances --instance-ids $instance_id
end
end
end
You can of course do all of this with the built in aws
CLI (I’m in fact doing eaxctly that), but remembering all that… nah.
ec2-cycle
Finally, something a bit different, a script to cycle a fleet of servers:
#!/usr/bin/env fish
if test (count $argv) -eq 1
set name $argv[1]
set time 60
else if test (count $argv) -eq 2
set name $argv[1]
set time $argv[2]
else
echo "Usage: ec2-cycle {name} {time=60}"
exit
end
echo "Cycling $name, waiting $time second(s) between each cycle"
for ip in (ec2 $name --ips)
echo $ip
yes | terminate $ip
sleep $time
end
It uses terminate
above, slow cycling instances 1 per every given number of seconds.