こちらの記事 AWS - bashだけで簡単ec2 ssh接続(踏み台対応) - Qiitaに触発されて、前から自分がほしかったものを書いてみた。
今の職場ではプロジェクトごとにAWSのアカウントが分かれており、さらに海外向けもあるので複数のリージョンを使っていたりで、管理するのがめんどくさい。都度プロファイルとリージョンを指定してコマンドを叩くのも面倒なので、credentialファイルにある全アクセスキーの全リージョンにあるEC2インスタンスの情報をとにかくもってきたい。
その後はpecoに任せて、SSH接続するなり、「m3.medium」とかで絞り込んでこのインスタンスタイプのEC2はこれだけあるのかとか見ながらニヤニヤするとかしたい。
ただEC2対応リージョンが現時点で8つあり、さらに複数のアカウントとなるとAPIを何度も投げる必要があり、シーケンシャルに実行するととても待ってられない。そこでGoとaws-sdk-goを使って、並列でインスタンス情報を持ってくるコマンドを書いてみた。アカウントが増えても大体2秒程度で結果が取れる。
(英語でREADMEも書いてみたけどむちゃくちゃなので誰か直してほしい・・・。)
インストール
リリースページにgoxでクロスコンパイルしたバイナリを置いてみたので、自分のプラットフォームに合ったバイナリをダウンロードしてきて、パスの通ったところに置けばいい。そのままだと名前が長すぎるのでリネームした方がいい。以下ではgo-ec2list
にリネームしたとして説明していく。
なお、Goの開発環境があればgo get github.com/sudix/go-ec2list
でもいい。
credentialファイルの準備
aws configure
コマンドとかでcredentialファイルを設定する。使いたいアカウント分だけ設定しておく。設定したら以下のようになっているはず。
~/.aws/credentials
[default]
aws_access_key_id = XXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXX
[project1]
aws_access_key_id = XXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXX
[project2]
aws_access_key_id = XXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXX
なお環境変数での指定には対応していない。
実行
とりあえず実行してみる。コマンド叩くだけ。
$ go-ec2list
結果
結果は以下のような感じで出力されるはず。(値はダミー)
admin_server i-xxxxxxxxx 52.xxx.xxx.xxx 172.xxx.xxx.xxx default ap-southeast-1a t2.small running
api_server1 i-xxxxxxxxx 52.xxx.xxx.xxx 172.xxx.xxx.xxx default ap-southeast-1a t2.small running
api_server2 i-xxxxxxxxx 52.xxx.xxx.xxx 172.xxx.xxx.xxx default ap-southeast-1a t2.micro running
app_server1 i-xxxxxxxxx 52.xxx.xxx.xxx 172.xxx.xxx.xxx project1 ap-southeast-1b m1.small running
app_server2 i-xxxxxxxxx 52.xxx.xxx.xxx 172.xxx.xxx.xxx project1 ap-southeast-1a m3.medium running
app_server1 i-xxxxxxxxx 52.xxx.xxx.xxx 10.xxx.xxx.xxx project2 ap-southeast-1b m1.small running
hoge_server1 i-xxxxxxxxx 10.xxx.xxx.xxx project2 ap-northeast-1c t2.micro stopped
nat_server i-xxxxxxxxx 52.xxx.xxx.xxx 172.xxx.xxx.xxx default ap-southeast-1b t2.micro stopped
Nameタグの昇順でソートしてから表示している。各行はタブ区切りとなっていて、出力される値は以下の順となっている。
- Instance Name
- Instance ID
- Public IP
- Private IP
- Profile Name
- Availability zone
- Instance type
- Instance state
キャッシュ
APIアクセスを待っても2秒程度で表示されるので自分が使う分にはこれで問題なかったけど、毎回数十回とかAPIアクセスするのはさすがに悪いと思ったので、キャッシュ機能も追加した。デフォルトでは無効だけど、-cachemin
オプションにキャッシュ有効期間(分単位)を指定すると、その間はキャッシュがあればそこから前回取得した情報を再表示する。
これだと10分間キャッシュ有効。
$ go-ec2list -cachemin 10
インスタンスを追加などして、キャッシュを更新したい場合は-refresh
を追加すれば、cacheminの値に関係なく最新情報を取得してくる。
$ go-ec2list -cachemin 10 -refresh
キャッシュは単なるファイルなので、手動で消してもいい。ファイルは以下に作られる。
$HOME/.go-ec2list/cache
pecoとの連携など
例えば全てのEC2インスタンスがパブリックにアクセス可能で、自分のマシンの公開鍵も登録しているとすると、
alias ec2="go-ec2list -cachemin 30 | peco | cut -f3 | xargs -I{} sh -c 'ssh "ec2-user@{}" </dev/tty' ssh"
こんな感じのaliasを登録すれば、pecoで絞り込んでSSHログインできる。
でも実際は踏み台経由でアクセスしたりするだろうし、インスタンス名やプロファイル名をみて接続方法を切り替えるようなスクリプトを後ろに置かないと使い物にならない。
苦労したところ
プロファイル一覧とか簡単に取れるだろうと思っていたら、aws-sdk-goにはそんな機能は無さそうだった。
仕方なく一旦プロファイル名を指定せずSharedCredentialsProviderを作り、そこからcredentialファイルのパスを取得、そのファイルをiniファイルとして読み込んでセクションとしてプロファイル一覧を取得、とかまわりくどいことをしている。
作ってみて
同じような悩みをもっている人はそんなにいないんじゃないかと思いながらも、個人的には便利に使っている。
Goとaws-sdk-goを使えばこの手のツールは量産できそうなので、みんなも作ればいいと思う。Let's 車輪の再発明。