人生やまあり

大学卒業後IT会社に就職してITをやってます。

jsonをコマンドで処理・加工できるjqを使って、一行でAWS EC2起動インスタンス一覧を表示する


<スポンサードリンク>

AWSのAPIを実行するとき何使ってますか?
私はパッと実行したいときはaws-cli、作りこみたいときはRuby SDKを使うことが多いです。

このawscli。使いやすくてシンプルでいいのですが、新しくなってレスポンスが完全にJSONになって、扱いにくて、、、
わざわざ「--output text」オプションつけて、前のaws-cliのときと同じタブ区切りで表示させてしてました。

aws ec2 describe-instances --output text

JSONってシェルとかには扱うのは大変ですよね。。。

JSON加工するのになにかいいのないかなーといろいろ調べてみると、、、jqというめっちゃ便利なもの発見!!!

jqとは?

jsonをいい感じに加工して表示してくれるコマンドです。

例えば

{"hoge": ["1", "2", "3"], "name" : "tanaka"}

というjsonがあったときに、これをjqを使って加工すると

echo '{"hoge": ["1", "2", "3"], "name" : "tanaka"}' | jq '.'
{
  "name": "tanaka",
  "hoge": [
    "1",
    "2",
    "3"
  ]
}

こんな感じで表示してくれます!

さらに

echo '{"hoge": ["1", "2", "3"], "name" : "tanaka"}' | jq '.name'
"tanaka"

こんな感じでキーからバリューを簡単に取り出すことが簡単にできます。
その他にselectを使ってifっぽい感じで条件文かいたり、出力をCSV形式で出力することもできます。(@shや@csv)

jqのインストール

インストールは本当に簡単。公式サイトからダウンロードしてPATHが通ったところに移動させて実行権限を与えるだけです。

curl -o /usr/bin/jq http://stedolan.github.io/jq/download/linux64/jq
chmod +x /usr/bin/jq
which jq

jqについての詳しいことは下記のサイトがお勧めです。
よく使う aws-cli 「私的」コマンドチートシートとか jq の使い方とか - ようへいの日々精進

AWS EC2起動インスタンス一覧を表示する

では本題。jqを利用して起動インスタンス一覧を取得してみます。

まずは認証のためのキーをexportコマンドで環境変数に読み込ませす。

[ec2-user@host ~]$ cat sbk_config
[default]
aws_access_key_id=YOUR_KEY
aws_secret_access_key=YOUR_SECRET_KEY
region=ap-northeast-1
[ec2-user@host ~]$ export AWS_CONFIG_FILE=~/config
[ec2-user@host ~]$

認証の設定が終わったら早速aws-cliを実行。

[ec2-user@host ~]$ aws ec2 describe-instances
{
    "Reservations": [
        {
            "OwnerId": "XXXXXXXXXXXX",
            "ReservationId": "r-XXXXXXXXX",
            "Groups": [],
            "Instances": [
・・・・

JSONですね(´・ω・`)

ではこのJSONをjqをつかってうまいこと加工していきましょう!!
まずはインスタンス一覧を。

[ec2-user@host ~]$ aws ec2 describe-instances | jq '.Reservations[].Instances[]'
{
  "AmiLaunchIndex": 0,
  "Tags": [
    {
      "Key": "Name",
      "Value": "XXXX"
    }
  ],
  "VirtualizationType": "paravirtual",
  "RootDeviceName": "/dev/sda1",
  "KernelId": "aki-XXXXXX",
  "Architecture": "x86_64",
  "BlockDeviceMappings": [
    {
      "Ebs": {
        "AttachTime": "2014-02-13T05:33:15.000Z",
        "VolumeId": "vol-XXXXXXXXXXX",
        "DeleteOnTermination": true,
        "Status": "attached"
      },
      "DeviceName": "/dev/sda1"
    }
  ],
  "Hypervisor": "xen",
  "Placement": {
    "AvailabilityZone": "ap-northeast-1a",
    "GroupName": null,
    "Tenancy": "default"
  },
・・・

いい感じに表示されてますね。

次は出力するキーを指定します。

[ec2-user@host ~]$ aws ec2 describe-instances | jq '.Reservations[].Instances[] |  {InstanceId, InstanceType, LaunchTime, State,Tags}'
{
  "Tags": [
    {
      "Key": "Name",
      "Value": "XXXXXX"
    }
  ],
  "State": {
    "Name": "running",
    "Code": 16
  },
  "LaunchTime": "2014-02-20T18:41:09.000Z",
  "InstanceType": "t1.micro",
  "InstanceId": "i-XXXXXXXX"
}
{
  "Tags": [
    {
・・・

これでインスタンス名、インスタンスID、Stateなどの情報を表示できましたね。
これに対して今度はselectを利用して「running」のインスタンスのみ表示させます。

[ec2-user@host ~]$ aws ec2 describe-instances | jq '.Reservations[].Instances[] \
| {InstanceId, InstanceType, LaunchTime, State,Tags} | select( .State.Name == "running" )'
{
  "Tags": [
    {
      "Key": "Name",
      "Value": "XXXXXX"
    }
  ],
  "State": {
    "Name": "running",
    "Code": 16
  },
  "LaunchTime": "2014-02-20T18:41:09.000Z",
  "InstanceType": "t1.micro",
  "InstanceId": "i-XXXXXXXX"
}
{
  "Tags": [
    {
・・・

これでrunnningのインスタンスのみを取り出すことに成功しました。
あとは用途に合わせてさらにjqを利用して必要な情報を取り出します。

起動中インスタンス名一覧

[ec2-user@host ~]$ aws ec2 describe-instances \
| jq '.Reservations[].Instances[] | {InstanceId, InstanceType, LaunchTime, State,Tags} \
| select( .State.Name == "running" )' | jq '.Tags[].Value'
"name1"
"name2"
[ec2-user@host ~]$

起動中インスタンスID一覧

[ec2-user@host ~]$ aws ec2 describe-instances \
| jq '.Reservations[].Instances[] | {InstanceId, InstanceType, LaunchTime, State,Tags} \
| select( .State.Name == "running" )' | jq '.InstanceId'
"i-XXXXXXXX"
"i-YYYYYYYY"

起動しているインスタンスをすべてストップする

これを使えば起動しているインスタンスを一度にすべて停止するスクリプトが簡単に書けてしまいます。ちょっと長いですが、

[ec2-user@host ~]$ for i in \
`aws ec2 describe-instances \
| jq '.Reservations[].Instances[] | {InstanceId, InstanceType, LaunchTime, State,Tags} \
| select( .State.Name == "running" )' | jq -r '.InstanceId'`; \
 do echo "Stop $i.; aws ec2 stop-instances --instance-ids $i";done
Stop i-XXXXXX.
Stop i-YYYYYY.
Stop i-ZZZZZZ.
・・・・・

いかがでしたでしょうか。
最近JSONがいろんなところで使われていますし、是非みなさんも使ってみてください^^