AWS EC2インスタンスのIPアドレスを即座に確認する
はじめに
サービスを運用しているエンジニアなら障害検知システムを導入して、日々の障害に備えているかと思います。
自身が所属するプロジェクトではAWSをメインに使っていて、監視サービスが異常を検知した場合、slackにインスタンスのホスト名を表示しています。
すぐにsshして詳細を確認したいけど、DNS設定していないインスタンスはIPでなければsshできません。
一刻も早く確認したいのに、毎回AWSコンソールに入ってEC2ダッシュボードからパブリックIP か プライベートIPを確認しなければいけないのは効率が悪い…。
これを機に インスタンス名やIPアドレスを一覧するコマンド を準備しようと思います。
※今回のやり方以外にも色々やりようはあるかと思いますが、自己流のやり方を記事に残しておきます。
前提
自身のプロジェクトでそれらのタグをつけていない場合は、今回のコマンドから不要な部分のコマンドを削除すればよいです。
1. とりあえず全て表示してみる
ベースとなるコマンドは aws ec2 describe-instancesです。
AWSで運用しているインスタンスの数によりますが、このまま叩くとEC2インスタンス情報が膨大なJSONにて表示されます。
2. 表示要素を絞り込む
JSONにはEC2インスタンスの様々な情報が含まれているため、必要最低限の要素だけを表示するようにします。
--query オプションを使うことでそれを指定できます。
検索パイプで渡して jq コマンドを実行している例もありますが、今は --query だけで事足りるようです。
$ aws ec2 describe-instances --query 'Reservations[].Instances[].{Env:Tags[?Key==`Environment`]|[0].Value,InstanceId:InstanceId,Name:Tags[?Key==`Name`]|[0].Value,PrivateIp:PrivateIpAddress,PublicIp:PublicIpAddress}' [ { "InstanceId": "i-XXXXXXX", "PublicIp": null, "Name": "host1", "Env": "Development", "PrivateIp": "10.XX.XXX.XXX" }, { "InstanceId": "i-XXXXXXX", "PublicIp": "13.XXX.XX.XX", "Name": "host2", "Env": "Production", "PrivateIp": "10.XX.XXX.XXX" }, { "InstanceId": "i-XXXXXXX", "PublicIp": null, "Name": "host3", "Env": "Staging", "PrivateIp": "10.XX.XXX.XXX" }, … ]
自分のプロジェクトでは、Environmentタグに環境名を、Nameタグにインスタンス名を設定しています。
"[?~]" で条件による絞り込みが可能です。値はバッククォートで囲います。
デフォルトだと配列形式の出力となり、Valueに対する項目名がわかりにくいので、MultiSelect Hashで連想配列にしています。
尚、Reservation とは インスタンスを起動するアクション のことです。
3. テーブル形式で出力する
JSON形式よりもヒューマンリーダブルなテーブル形式にします。
こちらはコマンドに --output table を追加するだけです。
$ aws ec2 describe-instances --query 'Reservations[].Instances[].{Env:Tags[?Key==`Environment`]|[0].Value,InstanceId:InstanceId,Name:Tags[?Key==`Name`]|[0].Value,PrivateIp:PrivateIpAddress,PublicIp:PublicIpAddress}' --output table --------------------------------------------------------------------------------------------------------- | DescribeInstances | +-------------+----------------------+------------------------------+----------------+------------------+ | Env | InstanceId | Name | PrivateIp | PublicIp | +-------------+----------------------+------------------------------+----------------+------------------+ | Production | i-XXXXX1 | host1 | 10.XXX.X.XXX | 13.XXX.XXX.XXX | | Staging | i-XXXXX3 | host3 | 10.XXX.X.XXX | None | | Staging | i-XXXXX4 | host4 | 10.XXX.X.XXX | 13.XXX.XXX.XXX | | Development| i-XXXXX6 | host6 | 10.XXX.X.XXX | None | | Production | i-XXXXX2 | host2 | 10.XXX.X.XXX | None | | Staging | i-XXXXX5 | host5 | 10.XXX.X.XXX | None | …
4. 環境でソートする(最終形)
バラバラなまま表示することは運用上少ないので、環境名でソートします。
3. のコマンドの結果をパイプでつないで sort_by というソート関数を噛ませます。
今回ここが割りと肝だったのですが、Environmentタグを定義していないインスタンスがある場合、ソート関数を単純に追加すると下記エラーが起きます。
In function sort_by(), invalid type for value: None, expected one of: ['string'], received: "null"
なので、 not_null という関数で、Environmentタグの値がnullのインスタンスを事前に除外します。
上記2点を踏まえて変更した最終形のコマンドがこちらです。
$ aws ec2 describe-instances --query 'Reservations[].Instances[?not_null(Tags[?Key==`Environment`].Value)][].{Env:Tags[?Key==`Environment`]|[0].Value,InstanceId:InstanceId,Name:Tags[?Key==`Name`]|[0].Value,PrivateIp:PrivateIpAddress,PublicIp:PublicIpAddress}|sort_by(@,&Env)[]' --output table --------------------------------------------------------------------------------------------------------- | DescribeInstances | +-------------+----------------------+------------------------------+----------------+------------------+ | Env | InstanceId | Name | PrivateIp | PublicIp | +-------------+----------------------+------------------------------+----------------+------------------+ | Development| i-XXXXX1 | host1 | 10.XXX.X.XXX | 13.XXX.XXX.XXX | | Development| i-XXXXX2 | host2 | 10.XXX.X.XXX | None | | Development| i-XXXXX3 | host3 | 10.XXX.X.XXX | None | | Development| i-XXXXX4 | host4 | 10.XXX.X.XXX | None | | Development| i-XXXXX5 | host5 | 10.XXX.X.XXX | None | … | Staging | i-XXXXX10 | host10 | 10.XXX.X.XXX | None | | Staging | i-XXXXX11 | host11 | 10.XXX.X.XXX | 13.XXX.XXX.XXX | | Staging | i-XXXXX12 | host12 | 10.XXX.X.XXX | None | +-------------+----------------------+------------------------------+----------------+------------------+
これで必要最低限の全EC2インスタンス情報が表示されるようになりました。
A. ホスト名で絞りたい
特定のホスト名で絞りこんで表示したい場合は、3. のコマンドに対して --filter で絞り込むだけです。
$ aws ec2 describe-instances --filter 'Name=tag:Name,Values=host10' --query 'Reservations[].Instances[?not_null(Tags[?Key==`Environment`].Value)][].{Env:Tags[?Key==`Environment`]|[0].Value,InstanceId:InstanceId,Name:Tags[?Key==`Name`]|[0].Value,PrivateIp:PrivateIpAddress,PublicIp:PublicIpAddress}|sort_by(@,&Env)[]' --output table --------------------------------------------------------------------------------------------------------- | DescribeInstances | +-------------+----------------------+------------------------------+----------------+------------------+ | Env | InstanceId | Name | PrivateIp | PublicIp | +-------------+----------------------+------------------------------+----------------+------------------+ | Staging | i-XXXXX10 | host10 | 10.XXX.X.XXX | None | +-------------+----------------------+------------------------------+----------------+------------------+
4. のコマンドでもいいですが、このケースではnullチェックやsortは不要かと思います。
B. 環境で絞りたい
A. と同じく --filter をかけます。
$ aws ec2 describe-instances --filter 'Name=tag:Environment,Values=Staging' --query 'Reservations[].Instances[?not_null(Tags[?Key==`Environment`].Value)][].{Env:Tags[?Key==`Environment`]|[0].Value,InstanceId:InstanceId,Name:Tags[?Key==`Name`]|[0].Value,PrivateIp:PrivateIpAddress,PublicIp:PublicIpAddress}' --output table --------------------------------------------------------------------------------------------------------- | DescribeInstances | +-------------+----------------------+------------------------------+----------------+------------------+ | Env | InstanceId | Name | PrivateIp | PublicIp | +-------------+----------------------+------------------------------+----------------+------------------+ | Staging | i-XXXXX10 | host10 | 10.XXX.X.XXX | None | | Staging | i-XXXXX11 | host11 | 10.XXX.X.XXX | 13.XXX.XXX.XXX | | Staging | i-XXXXX12 | host12 | 10.XXX.X.XXX | None | +-------------+----------------------+------------------------------+----------------+------------------+
複数環境を指定したい場合は、バラバラに出力されないようにsortもかけたほうがよいです。
以上、どなたかのご参考になれば幸いです。