lycheejam's tech log

チラ裏のメモ帳 | プログラミングは苦手、インフラが得意なつもり。

AWS CLIとjqでCSVを作るワンライナーレシピ集

概要

EC2インスタンスやEBSの一覧をスプレッドシート(エクセル)で作成しなければいけない...みたいなツラミを味わってるのは自分だけじゃないはず。
練習がてら雑にメモに追記していっていたAWS CLIとjqを使ってCSV出力するワンライナーが結構な量溜まったので、整理も兼ねてブログ記事にしようかと。
基本的にjqの組み立てについての解説はせず、どんな情報が取れるかの補足のみ記載します。
出力はヘッダー付きCSVになります。

※改行して整形してますが、ワンライナーって言っていいよね...?ダメ...?

目次

前提

実行環境はWSLのUbuntuですが、Macでも動作を確認しています。
紹介するものに関しては、OS依存の動作の違いは特にないかと思います。(たぶん)

$ aws --version
aws-cli/2.2.22 Python/3.8.8 Linux/5.10.16.3-microsoft-standard-WSL2 exe/x86_64.ubuntu.20 prompt/off
$ jq --version
jq-1.6

ワンライナーレシピ集

EC2インスタンスの一覧を取得する

EC2インスタンスを一覧取得してCSV出力するワンライナーです。

$ aws ec2 describe-instances | \
  jq -r '.Reservations[].Instances[] |
  {
    TagName: .Tags | from_entries.Name
    , PrivateIpAddress
    , PublicIpAddress
    , InstanceId
    , InstanceType
    , AZ: .Placement.AvailabilityZone
    , State: .State.Name
  }' | jq -r -s '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' > list.csv

.Tags | from_entries.Nameとすることで、TagにNameが設定されていなくても一覧に出力されるようになります。
よくあるmapとselectの組み合わせだと、Nameが設定されてないと出力されないので。
.Tags | from_entries.{Tagキー}とすることで任意のTagを出力可能です。

最後のjq -r -s '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv'CSV用のヘッダーを追加してます。
これはStackOverflowから引っ張ってきました。

How to convert arbitrary simple JSON to CSV using jq? - Stack Overflow

リザーブインスタンスの一覧を取得する

リザーブインスタンスの一覧を取得してCSV出力するワンライナーです。

aws ec2 describe-reserved-instances | \
  jq -r '.ReservedInstances[] | {
    InstanceType
    , ProductDescription
    , InstanceCount
    , State
    , Start
    , End
    , CurrencyCode
    , FixedPrice
    , OfferingClass
    , OfferingType
  }' | jq -r -s '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' > list.csv

EBSボリュームの一覧を取得する

EBSボリュームの一覧を取得してCSV出力するワンライナーです。

aws ec2 describe-volumes | \
  jq -r '.Volumes[] | {
    AttachTime: .Attachments[].AttachTime
    , Device: .Attachments[].Device
    , InstanceId: .Attachments[].InstanceId
    , State: .Attachments[].State
    , VolumeId: .Attachments[].VolumeId
    , DeleteOnTermination: .Attachments[].DeleteOnTermination
    , AvailabilityZone
    , CreateTime
    , Encrypted
    , Size
    , SnapshotId
    , State
    , Iops
    , VolumeType
  }' | jq -r -s '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' > list.csv

AMIの一覧を取得する

AMIの一覧を取得してCSV出力するワンライナーです。

aws ec2 describe-images \
  --owners self | \
  jq -r '.Images[] | {
    CreationDate
    , ImageId
    , Name
    , Description
    , ImageLocation
    , SnapshotId: .BlockDeviceMappings[].Ebs.SnapshotId
  }' | jq -r -s '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv'

単品でAMIの情報を見たいときは下記の通り--filterをつけてAMI名を指定します。

aws ec2 describe-images \
  --owners self \
  --filter "Name=name,Values={AMI_NAME}" | \
  jq -r '.Images[] | {
    CreationDate
    , ImageId
    , Name
    , Description
    , ImageLocation
    , SnapshotId: .BlockDeviceMappings[].Ebs.SnapshotId
  }'

EBSスナップショットの一覧を取得する

aws ec2 describe-snapshots --owner-ids self | \
  jq -r '.Snapshots[] | {
    Description
    , Encrypted
    , OwnerId
    , Progress
    , SnapshotId
    , StartTime
    , State
    , VolumeId
    , VolumeSize
    , OwnerAlias
    , TagName: .Tags | from_entries.Name
  }' | jq -r -s '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' > list.csv

--filterでボリュームIDを指定することで個別のスナップショットの情報が取得できる。

aws ec2 describe-snapshots --filters "Name=volume-id,Values=vol-XXXXXXXXXXXXXXX,vol-XXXXXXXXXXXXXXX" | \
  jq -r -s '. | {
    Description
    , SnapshotId
    , StartTime
    , VolumeId
    , VolumeSize
  }'

RDSインスタンスの一覧を取得する

RDSインスタンスの一覧を取得してCSV出力するワンライナーです。

aws rds describe-db-instances | \
  jq -r '.DBInstances[] |
  {
    TagName: .TagList | from_entries.Name
    , DBInstanceIdentifier
    , DBInstanceClass
    , Engine
    , EngineVersion
    , AvailabilityZone
    , MultiAZ
    , StorageType
    , AllocatedStorage
  }' | jq -r -s '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' > list.csv

ELBの一覧を取得する

ELB(ALB)の一覧を取得してCSV出力するワンライナーです。

aws elbv2 describe-load-balancers | jq -r '.LoadBalancers[] | {
  LoadBalancerName
  , State: .State.Code
  , Type
  , CreatedTime
  }' | jq -r -s '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' > list.csv

雑感

他にVPC周りやらRoute53、S3、IAM周りのワンライナーがあったんですけど、整理に疲れたんでこのあたりで。
動作確認してないので動かないぞとかあれば教えてください。