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バインディングのようです)
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秒)
が入ってるものとします。)
#!/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}'