AWS CLIでAWSリソース一覧取得(PowerShell)

AWS
この記事は約9分で読めます。
スポンサーリンク

意味が無いとみんな分かっているけれどインフラの納品物としてパラメータシートの提出が求められます。
管理コンソールからコピペでやってもいいんですが、EXCELでの整形が面倒になってきたのでAWS CLIで一括取得する方法になります。
jqを使ってjson整形する例もありますが、個人的に取っつきにくかったのとスクリプトのメンテナンスが面倒そうだったので、ここでは「AWS CLIとPowerShellだけでCSV形式で一括取得する」方法を記載します。

取得できるデータを見てみる

CSV形式で出力するために、AWS CLIの出力はJSONで取得します。
他の形式でもいいかもしれないですが、今回の方法だとJSONを扱った方がメンテナンスが楽です。
EC2の情報だとこんな感じで1台のEC2情報がバラバラと表示されます。

> aws ec2 describe-instances
{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-XXXXXXXXXXXXXXX",
                    "InstanceId": "i-XXXXXXXXXXXXXXXXX",
                    "InstanceType": "t2.nano",
                    "KeyName": "XXXXXXX",
                    "LaunchTime": "2022-04-04T07:18:30+00:00",
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "Placement": {
                        "AvailabilityZone": "us-east-1b",
                        "GroupName": "",
                        "Tenancy": "default"
                    },
                    "PrivateDnsName": "ip-XX-XX-XX-XXX.ec2.internal",
                    "PrivateIpAddress": "XX.XX.XX.XX",
                    "ProductCodes": [],
                    "PublicDnsName": "ec2-XX-XX-XX-XX.compute-1.amazonaws.com",
                    "PublicIpAddress": "XX.XX.XX.XX",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },

必要な情報だけ取得するようにフィルタをかける

全部の情報が必要だったら全部CSVにするんですが、実際はそうではないはず。
ということで、必要な情報だけフィルタをかけます。
フィルタをかける場合は「–query」を使用します。

ImageIdだけ取得したい場合はこんな感じ。
「Reservations[].Instances[]」はデータを抽出する起点を指定します。
この部分が一番面倒ですが、気にする必要はありません。
元々のjsonデータを見るとReservationsの[]の中にInstancesの[]がありますね。そのあとの{}の中にEC2のデータが出力されているので、「Reservations[].Instances[]」に格納されているデータを対象とするということです。
次に出力対象のjsonのキーを指定するのですが、書き方に注意です。
指定するときはコロン「:」で区切って「表示名:取得するキー」という形にします。
この例だと「InstanceId1」が表示名で「InstanceId」が取得するjsonのキーになります。

>  aws ec2 describe-instances --query "Reservations[].Instances[].{ `
>> InstanceId1:InstanceId `
>> }" `
>> --output json
[
    [
        {
            "InstanceId1": "i-XXXXXXXXXXXXXXXX"
        }
    ]
]

jsonの階層構造対応

CSVで出力する場合にjsonのような階層構造のままではフラットなCSV形式での出力ができません。
では、階層構造部分をどうするのか?という部分を見ていきます。
例えば、この場合はMonitoringの中にあるStateの値を抽出する必要があります。

"Monitoring": {
    "State": "disabled"
},

この場合は配列として考えましょう。
Monitoringの配列要素「0」のStateを抽出するということになります。

> aws ec2 describe-instances --query "Reservations[].Instances[].{ `
>> InstanceId1:InstanceId, `
>> State1:[Monitoring][0].State `
>> }" `
>> --output json
[
    {
        "InstanceId1": "i-XXXXXXXXXXXXXXXX",
        "State1": "disabled"
    }
]

これを理解するとEBSのような階層構造も簡単です。

"BlockDeviceMappings": [
    {
        "DeviceName": "/dev/xvda",
        "Ebs": {
            "AttachTime": "2022-04-04T07:18:31+00:00",
            "DeleteOnTermination": true,
            "Status": "attached",
            "VolumeId": "vol-XXXXXXXXXXXXXXXX"
        }
    }
],

VolumeIdを抽出する場合はこんな感じになります。
ここで書き方が違うことに気づいたでしょうか。
BlockDeviceMappingsは[]を付けてないのにEbsは[]を付けています。

この違いは何かというと、階層が[]で定義されているか{}で定義されているかの違いです。
[]で定義している場合はキーを[]で囲まない、{}で定義している場合はキーを[]で囲むと覚えておきましょう。

> aws ec2 describe-instances --query "Reservations[].Instances[].{ `
>> InstanceId1:InstanceId, `
>> State1:[Monitoring][0].State, `
>> VolumeId1:BlockDeviceMappings[0].[Ebs][0].VolumeId `
>> }" `
>> --output json
[
    {
        "InstanceId1": "i-XXXXXXXXXXXXXXXX",
        "State1": "disabled",
        "VolumeId1": "vol-XXXXXXXXXXXXXXXX"
    }
]

CSVに変換する

ここまではjsonをフラットに変換しただけです。
これをCSVに出力する場合はPowerShellのコマンドで変換します。
一度json形式でファイルに出力しそれをCSVに変換します。

aws ec2 describe-instances --query "Reservations[].Instances[].{ `
InstanceId1:InstanceId, `
State1:[Monitoring][0].State, `
VolumeId1:BlockDeviceMappings[0].[Ebs][0].VolumeId `
}" `
--output json > ec2.json
(Get-content ec2.json -Raw | ConvertFrom-Json) | Convertto-CSV -noTypeInformation > ec2.csv

ec2.csvをみるとこんな感じでCSVになります。

"InstanceId1","State1","VolumeId1"
"i-XXXXXXXXXXXXXXXX","disabled","vol-XXXXXXXXXXXXXXXX"

タイトルとURLをコピーしました