EC2/Win の Software Inventory を作ってみた。 Describe して DynamoDB に Put。lambda/python 3.8 で。

動作イメージ。
1．ec2/describe_instances を実行し、InstanceIDを取得
2．「1」で取得した InstanceID を引数として、ssm/list_inventory_entries を実行し、Software の Entry を取得
3．「1」と「2」の結果を引数として、dynamodb.put_item を実行し、DDBテーブルに入力。
を繰り返す。

以下では、各ステップの動作を確認した上で、最後にがっちゃんこする。

###Step1. EC2のリストを取得してみる。
```python:lambda
import boto3
import json

def lambda_handler(event, context):

    #EC2クライアント定義
    ec2_client = boto3.client('ec2')

    #EC2インスタンスのリストを取得するため、describe。
    response = ec2_client.describe_instances()

    #インスタンス台数分Inventoryを取得するので for 文で回す
    for reservation in response["Reservations"]:
        for instance in reservation['Instances']:
            instanceid = instance['InstanceId']

            #表示
            print("isntanceid=", instanceid)
```

```xx:結果
START RequestId: a78df98a-3952-414a-9499-xxxxxxxxxxxx Version: $LATEST
isntanceid= i-xxxxxxxxxxxx
isntanceid= i-yyyyyyyyyyyy
isntanceid= i-zzzzzzzzzzzz
```

### step2. Systems Manager でマネージドインスタンスとなっている EC2 のインベントリを取得してみる。

```python:lambda
import boto3
import json

def lambda_handler(event, context):

    #テスト用にインスタンスIDを定義
    instanceid = 'i-xxxxxxxxxxxx'

    #ssmクライアントの定義
    ssm_client = boto3.client('ssm')
    
    #対象インスタンスの software inventory を describe で取得
    response = ssm_client.list_inventory_entries(
        InstanceId = instanceid,
        TypeName ='AWS:Application'
        )
    
    #各エントリの名前とバージョンを抽出
    for entry in response["Entries"]:
        name = entry['Name']
        version = entry['Version']
        instanceid_name = instanceid + '_'+ name

        #表示
        print("isntanceid, name, version=", instanceid, name, version)
        

```

```aaa:結果
START RequestId: 46c935c9-9015-4de8-acce-xxxxxxxxxxxx Version: $LATEST
isntanceid, name, version= i-xxxxxxxxxxxx libpath_utils 0.2.1
isntanceid, name, version= i-xxxxxxxxxxxx kbd-misc 1.15.5
isntanceid, name, version= i-xxxxxxxxxxxx libsss_nss_idmap 1.16.5
isntanceid, name, version= i-xxxxxxxxxxxx basesystem 10.0
isntanceid, name, version= i-xxxxxxxxxxxx coreutils 8.22
````

###Step3.dynamoddb に投入してみる。
※テーブルは事前につくってある前提

```python:lambda
import json
import boto3

#DDBに突っ込む関数
def lambda_handler(event, context):
    
    #テーブルは事前に作成
    table_name = 'software-inventory'
    
    #テーブルに挿入する各行をitemとして定義
    item = {
        "instanceid_name": instanceid_name,
        "instanceid": instanceid,
        "software-name": name,
        "software-version": version
        }
        
    #dynamodbクライアント定義
    dynamodb_client = boto3.resource('dynamodb')

    #テーブルに入力
    dynamodb_table = dynamodb_client.Table(table_name)
    dynamodb_table.put_item(Item=item)
```

###Step4.Step1 ~ Step3をくっつけてみる。
```python:lambda
import json
import boto3

#DDBに突っ込む関数
def insert_ddb(instanceid_name, instanceid, name, version):
    
    #テーブルは事前に作成
    table_name = 'software-inventory'
    
    #テーブルに挿入する各行をitemとして定義
    item = {
        "instanceid_name": instanceid_name,
        "instanceid": instanceid,
        "software-name": name,
        "software-version": version
        }
        
    #dynamodbクライアント定義
    dynamodb_client = boto3.resource('dynamodb')

    #テーブルに入力
    dynamodb_table = dynamodb_client.Table(table_name)
    dynamodb_table.put_item(Item=item)

#Software inventory を持ってくる関数
def get_inventory(instanceid):

    #ssmクライアントの定義
    ssm_client = boto3.client('ssm')
    
    #対象インスタンスの software inventory を describe で取得
    response = ssm_client.list_inventory_entries(
        InstanceId = instanceid,
        TypeName ='AWS:Application'
        )
    
    for entry in response["Entries"]:
        name = entry['Name']
        version = entry['Version']
        #DynamoDBにおけるプライマリーキー的な役割として、InstanceIDとSoftware名をがっちゃんこ。
        instanceid_name = instanceid + '_'+ name

        #insert 関数を呼び出し
        insert_ddb(instanceid_name, instanceid, name, version)

#メイン 
def lambda_handler(event, context):

    #EC2クライアント定義
    ec2_client = boto3.client('ec2')

    #EC2インスタンスのリストを取得するため、describe。
    response = ec2_client.describe_instances()

    #インスタンス台数分Inventoryを取得するので for 文で回す
    for reservation in response["Reservations"]:
        for instance in reservation['Instances']:
            instanceid = instance['InstanceId']

            #inventory取得用の関数を呼び出し。引数はInstanceID
            get_inventory(instanceid)
```