はじめに
現状のAWSで使用しているリソース(EC2など)の一覧表(Excel)を作成するため、AWS CLIとjqを使ってcsv形式のリストを作成した。
使用した環境は以下の通り。
- OS:Windows10
- PowerShell:5.1
- AWS CLI:2.2.11
- jq:1.6
AWS CLIでリソース情報を出力できるようにする
AWS CLI = AWS Command Line Interface
これをインストールするとコマンドライン(=スクリプト形式)でAWS上のリソースの操作、情報取得ができる。
コンソールでIAMユーザを作成する
- AWS CLIでリソース情報を読み取るためのIAMユーザを作成する。
- 「AWSアクセスの種類を選択」で、「プログラムによるアクセス」を選択する。
- アクセス権限として、「arn:aws:iam::aws:policy/ReadOnlyAccess」のポリシーのみを付与する。
(リソース操作はできないが、ほとんど全てのリソース情報を読み取れてしまうので注意)
- 表示されるアクセスキーIDと、シークレットアクセスキーをダウンロードして保存する。
AWS CLIをインストールする(Windowsの場合)
参考:(https://gihyo.jp/admin/serial/01/awscli_diary/0001?page=1)
- AWS CLIの公式ページから、インストーラをダウンロード
- インストーラでAWS CLIをインストール
- PowerShellで以下を実行し、バージョンが表示されていればOK
> aws --version
aws-cli/2.2.11 Python/3.8.8 Windows/10 exe/AMD64 prompt/off
ちなみに、pipでもインストール可能。
> pip3 install awscli
AWS CLIの初期設定
以下を実行し、設定情報を入力する。
(この設定は後から変更も可能)
> aws configure
AWS Access Key ID [None]: (ダウンロードしたアクセスキーID)
AWS Secret Access Key [None]: (ダウンロードしたシークレットアクセスキー)
Default region name [None]: ap-northeast-1a (確認したいリソースのリージョンを入力)
Default output format [None]: json
実際に出力してみる
以下のコマンドを実行する。
> aws ec2 describe-instances
以下のようにJSON形式でリソースの情報が表示される。
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "xxx",
"InstanceId": …
使用できるコマンドについては以下を参照。
AWS CLI Command Reference
以下のように表示内容をファイル出力することも可能。
> aws ec2 describe-instances >> ec2.json
jqをインストール
jqはコマンドライン上で使用できるJSONパーサー。JSON形式のデータのフィルタリング等が可能。
ここからインストーラをダウンロード、インストールする。
Powershellで以下のコマンドでバージョン確認できればOK
> jq --version
jq-1.6
リソースごとのcsvファイルを作成する
EC2のリソース情報をjq経由でcsvファイルに出力する
実際に出力に使ったコマンドは以下の通り。
aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | if .Tags then . else .Tags = [] end | [
.InstanceId,
( .Tags[] | select(.Key == \"Name\") | .Value)// \"\",
( .Tags[] | select(.Key == \"Owner\") | .Value ) // \"\",
.InstanceType,
.Placement.AvailabilityZone,
.VpcId,
.SubnetId,
.KeyName,
.PublicIpAddress,
.SecurityGroups[].GroupName,
.SecurityGroups[].GroupId,
.BlockDeviceMappings[].Ebs.VolumeId ,
.NetworkInterfaces[].Attachment.AttachmentId,
.NetworkInterfaces[].Groups[].GroupName,
.NetworkInterfaces[].Groups[].GroupId
] | @csv' >> ec2_list.csv
SecurityGroup、BlockDeviceMappings、NetworkInterfacesはアタッチしている数がインスタンスごとに変わるので、場合によっては行ごとに列数が変わってしまう。(Excel上で修正するか、そもそも出力しないか)
以下、簡単な解説
# AWS CLIでJSON形式のデータを取得
aws ec2 describe-instances
# jqを同時に呼び出してJSON形式のデータを加工、-rは要素についている""を外す
# jq -オプション 'フィルタ' の形式で実行
| jq -r '.Reservations[] ... '
# "Instances"の中に[]で配列状に入っているデータを全て取得対象にする
.Instances[]
# "Tags" の項目がある場合は値をそのまま使用し、ない場合は[](空の配列)を返す
# if ~ then ~ else ~ end の形で必ず書く
| if .Tags then . else .Tags = [] end
# パイプ以降に[]をつけて出力したい項目を配列として出力する
# .InstanceId, 以降は出力したい項目を入力する
| [
.InstanceId,
# Tagは取り出したいKeyの値をselect文で取り出す
# // "" で、取得値がnullだった時のデフォルト値を""(空文字)とする、""はPowerShellだとエラーになるので\でエスケープする
( .Tags[] | select(.Key == \"Name\") | .Value) // \"\",
# @csv を利用して、CSV形式で出力
'... ] | @csv' >> ec2_list.csv
EBSの場合
aws ec2 describe-volumes | jq -r '.Volumes[] | if .Tags then . else .Tags = [] end | [
.VolumeId,
( .Tags[] | select(.Key == \"Name\") | .Value) // \"\",
( .Tags[] | select(.Key == \"Owner\") | .Value ) // \"\",
.AvailabilityZone,
.Size,
.Iops,
.State,
.SnapshotId,
.Attachments[].InstanceId,
.Attachments[].VolumeId
] | @csv' >> ebs_list.csv
NetworkInterfaceの場合
aws ec2 describe-network-interfaces | jq -r '.NetworkInterfaces[] | [
.NetworkInterfaceId,
( .TagSet[] | select(.Key == \"Name\") | .Value) // \"\",
( .TagSet[] | select(.Key == \"Owner\") | .Value ) // \"\",
.Description,
.InterfaceType,
.AvailabilityZone,
.VpcId,
.SubnetId,
.Status,
.Groups[].GroupName,
.Groups[].GroupId,
.Association.PublicIp,
.Attachment.AttachmentId,
.Attachment.InstanceId,
.Attachment.InstanceOwnerId
] | @csv' >> nif_list.csv
参考
【小ネタ】aws-cliでEC2マネージメントコンソールの内容をCSVに出力する
軽量JSONパーサー『jq』のドキュメント:『jq Manual』をざっくり日本語訳してみました
コマンドラインJSONプロセッサー jqの演算子と関数
配列やnull(特定のキーがない)があるJSONからjqでTSV作ってみた
雑感
SecurityGroupなどはインバウンドルールの数がグループごとに全く異なる場合が多いので、csv出力に向いていない。JSONファイルをプログラムで処理した方がいいかも。
IAMユーザは所属するグループ情報も取得したい場合は
aws iam list-groups-for-user \
--user-name USERNAME \
のようにユーザ名を指定する必要があるため、スクリプトを組んだ方がよい。もしくは、[Former2]を使ってCloudFormation形式のテンプレートに出力して変換するのもありかと。