LoginSignup
13
15

More than 5 years have passed since last update.

jqやpecoと組み合わせてaws-cliを便利に使う

Last updated at Posted at 2015-01-10

EC2 InstanceのPrivateIpAddressと名前の一覧

/etc/hosts風に出力:

$ aws ec2 describe-instances | jq . > instances.json
$ cat instances.json | jq -r '.Reservations[] | .Instances[] | [.PrivateIpAddress,.InstanceId,"# "+(.Tags[] | select(.Key == "Name") | .Value // "")] | join("\t")'
172.31.16.30    i-0610880b  # test
172.31.48.10    i-94c9199b  # nat

runningだけをpecoで選んでsshする:

$ eval `cat instances.json | jq -r '.Reservations[] | .Instances[] | select(.State.Name == "running") | ["ssh",.PrivateIpAddress,"# "+(.Tags[] | select(.Key == "Name") | .Value // "")] | join("\t")' | peco`

CloudFormationでローカルのテンプレートファイルでスタック作成・アップデート

テンプレートに空白とかが入ってても""で括るだけで渡せるのか〜

$ aws cloudformation update-stack --stack-name iam-role-test --template-body "`cat iam-role.json`" --parameters ParameterKey=AllowAction,ParameterValue=s3:List* --capabilities CAPABILITY_IAM

SQSのメッセージのBodyをdecodeし、さらにその中のSNSのMessageをdecodeする

例えばAutoScalingのNotificationをSNS経由でSQSに飛ばした場合、AutoScalingからの通知のJSONが、文字列にエンコードされてSNSのMessageに入り、そのSNSからの通知のJSONが、SQSのBodyに文字列にエンコードされて入っています。

fromjsonという関数で、JSON文字列をJSONに変換できるんですね!

aws sqs receive-message --queue-url https://sqs.us-west-2.amazonaws.com/123456789012/sys-status > message.json
cat message.json | jq '.Messages[0].Body | fromjson | .Message | fromjson'

複数のjsonファイルをディープマージしたい

cat *.json | jq -s 'reduce .[] as $obj ({}; . * $obj)'

jqの出力結果をRubyで使いたい

jqで[]とかを使って結果が複数になる場合、Rubyの標準のJSONモジュールでは読み込めません。(バラさずに配列のまま、mapを使って処理を連結することもできますが、面倒です)

yajl-rubyというgemで、複数のJSONが連なったストリームを読み込んで処理することができます。(Yet Another JSON LibraryというC実装のRubyバインディングのようです)

Gemfile
gem 'yajl-ruby', require: 'yajl'

例えば、aws ec2 describe-instancesを、jqでinstance単位にバラした結果を、YAMLで見たい場合:

aws ec2 describe-instances | jq -S '.Reservations[].Instances[]' | bundle exec ruby -ryajl -ryaml -e 'Yajl::Parser.parse(STDIN){|h| puts YAML.dump h}'

古いAMIのうちAutoScalingで使っていないものだけ削除

Packerとかで毎週AMIをビルドしてると、古いAMIをまとめて消したくなりますが、
うっかりAutoScalingGroupで使ってるAMIを消してしまうと、
次にインスタンスが起動する際、起動に失敗し続けて、大惨事になります。

そこで、2週間より古いAMIから、現在AutoScalingGroupで参照されているものを除いた
ImageIdの一覧を表示します。

(ビルドするAMIのTagに、"timestamp"というキーで、タイムスタンプ(Epoch秒)
が入ってるものとします。)

gc_image
#!/bin/bash

aws autoscaling describe-launch-configurations | jq . > tmp/launch-configurations.json

cat tmp/launch-configurations.json | jq -r '.LaunchConfigurations[] | .ImageId' | sort | uniq > tmp/used.txt

aws ec2 describe-images --owners self | jq . > tmp/images.json

# 2 weeks ago
time=`date -v-14d +%s`

echo "Old AMIs:"
cat tmp/images.json | jq -r --arg time $time '.Images[] | [.ImageId, ((.Tags // empty) | map(select(.Key=="timestamp"))[0] | .Value), .Name] | select(. | length > 2) | select((.[1] | tonumber) < ($time | tonumber)) | join(" ")' | sort | tee old.txt

echo "Used AMIs:"
cat tmp/images.json | jq -r --arg ids "`cat tmp/used.txt`" '.Images[] | [.ImageId, ((.Tags // empty) | map(select(.Key=="timestamp"))[0] | .Value), .Name] | select(.[0] as $id | ($ids | split("\n")) | contains([$id])) | join(" ")' | sort | tee used.txt

echo "Old unused AMIs:"
diff old.txt used.txt | awk '/^</{print $2, $3, $4}'

参考

13
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
15