たった3コマンドでAWSリソースの見れる一覧を作成する

ある日突然Excel方眼紙好きの上司（権限を持っていてもAWSコンソール上へは頑なにサインインしようとしないものとする）から「AWSで使用しているリソースの一覧を作成せよ」との命を受けたとします。
本稿に記載の3コマンドをコピペしてExcelで見れる一覧を軽々と作成する事で、今日から貴方も出来るエンジニアに成りましょう！

#環境情報
コマンドはEC2インスタンス上で実行します。
使用した環境のOS, カーネル, AWSCLI, jqコマンドのバージョンは以下の通りです。

```shell-session:バージョン確認
$ cat /etc/system-release
Amazon Linux release 2 (Karoo)
$ uname -a
Linux hogehuga.ap-northeast-1.compute.internal 4.14.77-81.59.amzn2.x86_64 #1 SMP Mon Nov 12 21:32:48 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ aws --v
aws-cli/1.15.80 Python/2.7.14 Linux/4.14.77-81.59.amzn2.x86_64 botocore/1.10.79
$ yum list installed | grep jq 
jq.x86_64                             1.5-1.amzn2.0.2                @amzn2-core
```

json解析用の`jq`コマンドがもしインストールされていなければ以下コマンド等を用いてインストールします。

```shell-session
# yum -y install jq
```

#権限設定
一覧作成コマンドを使用するEC2インスタンスに、以下のポリシーがアタッチされたIAMロールを割り当てます。
※`aws configure`コマンドでも権限の付与は可能ですがセキュリティの観点からAWSベストプラクティスに従ってIAMロールを使用する方が良いです。

```json:EC2のみ権限を付与する場合
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*"
        }
    ]
}
```

```json:RDSのみ権限を付与する場合
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "rds:DescribeDBInstances",
            "Resource": "*"
        }
    ]
}
```

```json:Elasticacheのみ権限を付与する場合
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "elasticache:DescribeCacheClusters",
            "Resource": "*"
        }
    ]
}
```

```json:上記3サービスの権限を全て付与する場合
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "rds:DescribeDBInstances",
                "elasticache:DescribeCacheClusters"
            ],
            "Resource": "*"
        }
    ]
}
```

#一覧作成
##EC2
```shell-session:
$ aws ec2 describe-instances | jq -r '.Reservations[].Instances[]' > ec2_instance_list.json

$ echo '"Name","インスタンスの状態","インスタンスID","インスタンスタイプ","VPC ID","テナンシー","アベイラビリティゾーン","プラットフォーム","パブリック DNS (IPv4)","IPv4 パブリックIP","プライベート IP"' > ec2_instance_list.csv
$ aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | [ ( .Tags[]| select(.Key == "Name") | .Value ) // "", .State.Name, .InstanceId, .InstanceType, .VpcId, .Placement.Tenancy, .Placement.AvailabilityZone, .Platform, .PublicDnsName, .PublicIpAddress, .PrivateIpAddress ] | @csv' >> ec2_instance_list.csv
$ iconv -f UTF-8 -t SHIFT_JIS ec2_instance_list.csv > ec2_instance_list-shift_jis.csv
```

##RDS
```shell-session:
$ aws rds describe-db-instances > rds_instance_list.json

$ echo '"DB 識別子","DB クラスター識別子","ステータス","サイズ","エンジン","エンジンバージョン","ストレージタイプ","ストレージ","IOPS","リージョンと AZ","マルチ AZ","DB サブネットグループ名","VPC ID","パラメータグループ","パフォーマンスインサイト","バックアップ保持期間","バックアップウィンドウ","マイナーバージョン自動アップグレード","メンテナンスウィンドウ","作成時刻"' > rds_instance_list.csv
$ aws rds describe-db-instances | jq -r '.DBInstances[] | [  .DBInstanceIdentifier, .DBClusterIdentifier, .DBInstanceStatus, .DBInstanceClass, .Engine, .EngineVersion, .StorageType, .AllocatedStorage, .Iops, .AvailabilityZone, .MultiAZ, .DBSubnetGroup.DBSubnetGroupName, .DBSubnetGroup.VpcId, .DBParameterGroups[].DBParameterGroupName, .PerformanceInsightsEnabled, .BackupRetentionPeriod, .PreferredBackupWindow, .AutoMinorVersionUpgrade, .PreferredMaintenanceWindow, .InstanceCreateTime ] | @csv' >> rds_instance_list.csv
$ iconv -f UTF-8 -t SHIFT_JIS rds_instance_list.csv > rds_instance_list-shift_jis.csv
```

##Elasticache
```shell-session:
$ aws elasticache describe-cache-clusters > elasticache_node_list.json

$ echo '"ノード名","クラスター名","ステータス","ノードのタイプ","モード","エンジンのバージョン","送信中の暗号化","保管時の暗号化","アベイラビリティーゾーン","サブネットグループ","パラメータグループ","バックアップの保存期間","バックアップウィンドウ","マイナーバージョン自動アップグレード","メンテナンスウィンドウ","クラスター作成時刻"' > elasticache_node_list.csv
$ aws elasticache describe-cache-clusters | jq -r '.CacheClusters[] | [  .CacheClusterId, .ReplicationGroupId, .CacheClusterStatus, .CacheNodeType, .Engine, .EngineVersion, .TransitEncryptionEnabled,.AtRestEncryptionEnabled, .PreferredAvailabilityZone, .CacheSubnetGroupName, .CacheParameterGroup.CacheParameterGroupName, .SnapshotRetentionLimit, .SnapshotWindow, .AutoMinorVersionUpgrade, .PreferredMaintenanceWindow, .CacheClusterCreateTime ] | @csv' >> elasticache_node_list.csv
$ iconv -f UTF-8 -t SHIFT_JIS elasticache_node_list.csv > elasticache_node_list-shift_jis.csv
```

それぞれのコマンドでは以下の処理を実行しています。

1. 行目：各サービスのリソース一覧をほぼ未加工のjson形式で作成します。
    1. 作成したjsonは抜き出したい項目を手動で確認する場合に使用しました。
    1. 一覧を作成するだけなら実行不要です。
1. 行目：一覧のヘッダーをcsvファイルの先頭行に書き込んでいます。
    1. 一覧にヘッダー行が不要であれば実行不要です。
1. 行目：返り値(json)から欲しいデータだけをcsv形式で抜き出して、指定ファイルに追記しています。
1. 行目：作成したcsvファイルのshift_jis版ファイルを変換して作成します。
    1. ヘッダーに日本語を使用している為にcsvをExcelで開いた際に文字化けしてしまう問題の対処です。
    1. Excelを使用しない場合やヘッダーに文字化けする文字（日本語等）を使用しない場合は実行不要です。

3行目のみ実行した場合でも一覧の作成は可能です。
取得するインスタンスIDを指定したり、インスタンスの状態によって取得するインスタンスをフィルターしたい場合は、[AWS CLIを使ってEC2インスタンスの情報を取得する - Qiita](https://qiita.com/toshiro3/items/37821bdcc50c8b6d06dc)を参考に`--instance-ids`オプションや`--filter`オプションを用いてフィルタリングします。

#参考
[マネジメントコンソールで参照可能なサービスを制限する ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/iam-policy-manage-console/)
[AWS CLIを使ってEC2インスタンスの情報を取得する - Qiita](https://qiita.com/toshiro3/items/37821bdcc50c8b6d06dc)
[軽量JSONパーサー『jq』のドキュメント：『jq Manual』をざっくり日本語訳してみました ｜ Developers.IO](http://dev.classmethod.jp/tool/jq-manual-japanese-translation-roughly/)

[describe-instances — AWS CLI 1.16.211 Command Reference](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html)
[describe-db-instances — AWS CLI 1.16.211 Command Reference](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-instances.html)
[describe-cache-clusters — AWS CLI 1.16.211 Command Reference](https://docs.aws.amazon.com/cli/latest/reference/elasticache/describe-cache-clusters.html)

[Linux ファイルの文字コード確認・変換 - Qiita](https://qiita.com/H_Neco/items/48fa2eaaa0d9af2e45fe)