マルチアカウント構成でのSSM Inventoryによるインベントリ収集方法

# 初めに
今回は、<font color="deeppink">__SSM Inventory__</font>を使ったマルチアカウント環境でのInventory情報の収集方法について解説します。

# SSM Inventoryとは

SSM AgentがインストールされたEC２やオンプレミスのサーバから、そのサーバのメタデータを収集する機能し、一覧表示する機能です。
詳細はblackbeltをご参照ください。

![0-blackbelt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/3ceee1dc-ba76-5adc-6b0c-f0486da54b8e.png)
（引用元：[20200212 AWS Black Belt Online Seminar AWS Systems Manager](https://www.slideshare.net/AmazonWebServicesJapan/20200212-aws-black-belt-online-seminar-aws-systems-manager)の35ページ)


収集できるインベントリはこちら。
カスタムインベントリについては別のブログで書きたいと思います。
![0-blackbelt2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/dcc5b94a-0a5b-e78e-b0e1-4aa93a8623bb.png)

（引用元：[20200212 AWS Black Belt Online Seminar AWS Systems Manager](https://www.slideshare.net/AmazonWebServicesJapan/20200212-aws-black-belt-online-seminar-aws-systems-manager)の36ページ)

# なぜ検証したのか？
複数の部署で異なるシステムを管理しているお客様からの依頼により検証しました。
お客様はそれぞれのシステムでどのようなアプリやWindowsサービスが稼働しているのかを管理するためにエクセルをご利用でした。
それはしんどいということで、運用を簡素化するために<font color="deeppink">__SSM Inventory__</font>が有効かどうかを検証することになりました。

# お客様環境の構成
部署ごとにAWSアカウントを持ち、セキュリティやログ管理用に管理者アカウントがある __マルチアカウント構成__ です。

![0-multiaccount.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/e540a10a-da5d-6bb7-8d48-c083acb33c2b.png)



# SSM Inventoryの構成
構成はとてもシンプルです。
__中央アカウント側で__ S3バケットを作って、__中央と部署のアカウントそれぞれで__ SSM Inventoryの「リソースデータの同期」を作るだけ。

![0-simple-gaiyo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/afead699-af00-7d3a-d757-f05cb3f28dc0.png)


# 構築手順
1. [管理者アカウント]S3バケットを作成
2. [管理者アカウント]SSM Inventoryの「リソースデータの同期」を作成
3. [部署アカウント]SSM Inventoryの「リソースデータの同期」を作成

## 1. [管理者アカウント]S3バケットを作成
S3バケットを作成します。
* バケット名：任意のバケット名
* AWSリージョン：アジアパシフィック(東京)ap-northeast-1
* デフォルトの暗号化：「有効にする」を選択し、SSE-S3とする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/ffe96775-91d0-2060-42cc-bd142654cd10.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/42ab458a-fb87-248a-02dc-dbf5f05a68d8.png)


上記以外はデフォルトの設定とします。

__バケットポリシー__ の設定も必要です。
設定するべきポリシーについては公式ドキュメントに記載がされています。

[インベントリのリソースデータの同期の設定](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-inventory-datasync.html#sysman-inventory-datasync-before-you-begin)


実際は上記記載のバケットポリシーの記載のうちConditionの部分を少し変更しなくてはいけません。
ドキュメントでは __StringEquals__ 、__ArnLike__ を使っていますが
複数AWSアカウントのSSMから、S3へインベントリデータをputできるよう、集合演算子 __「ForAnyValue」__ を利用します。

```json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SSMBucketPermissionsCheck",
      "Effect": "Allow",
      "Principal": {
        "Service": "ssm.amazonaws.com"
      },
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::管理者アカウントのS3バケット名"
    },
    {
      "Sid": " SSMBucketDelivery",
      "Effect": "Allow",
      "Principal": {
        "Service": "ssm.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": [
        "arn:aws:s3:::管理者アカウントのS3バケット名/*/accountid=部署AアカウントのAWSアカウントID/*",
        "arn:aws:s3:::管理者アカウントのS3バケット名/*/accountid=部署BアカウントのAWSアカウントID/*",
        "arn:aws:s3:::管理者アカウントのS3バケット名/*/accountid=部署CアカウントのAWSアカウントID/*"
      ],
      "Condition": {
        "ForAnyValue:StringEquals": {
          "aws:SourceAccount": [
              "管理者アカウントのAWSアカウントID",
              "部署AアカウントのAWSアカウントID",
              "部署BアカウントのAWSアカウントID",
              "部署CアカウントのAWSアカウントID"
            ],
          "s3:x-amz-acl": "bucket-owner-full-control"
        },
        "ForAnyValue:ArnLike": {
          "aws:SourceArn": [
            "arn:aws:ssm:*:管理者アカウントのAWSアカウントID:resource-data-sync/*",
            "arn:aws:ssm:*:部署AアカウントのAWSアカウントID:resource-data-sync/*",
            "arn:aws:ssm:*:部署BアカウントのAWSアカウントID:resource-data-sync/*",
            "arn:aws:ssm:*:部署CアカウントのAWSアカウントID:resource-data-sync/*"
          ]
        }
      }
    }
  ]
}

```

特定のリソースデータ同期からのみS3への書き込みを許可したい場合は
``` json
"ForAnyValue:ArnLike": {
  "aws:SourceArn": [
    "arn:aws:ssm:${Region}:AWSアカウントID:resource-data-sync/${SyncName}",
    "arn:aws:ssm:${Region}:AWSアカウントID:resource-data-sync/${SyncName}"
  ]
}
```
と書きます。

## 2. [管理者アカウント]SSM Inventoryの「リソースデータの同期」を作成

<font color="deeppink">Systems Manager</font>からフリートマネージャーを選択し、
「アカウント管理」から「リソースデータの同期」を選択します。

![0-fleetmanager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/3cdb081b-c8e1-9541-1735-9cf8545f8ebe.png)
![0-sync.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/e486181f-849c-0ff9-3e94-9504a3fba02a.png)

![1-inventory-create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/440e5c9b-b4d9-1c92-4f32-8dc7b995d3ae.png)



任意のリソースデータ同期名と、先ほど設定したS3バケット名を指定します。
リージョンはap-northeast-1を指定します。

S3 prefixは指定した場合としなかった場合との挙動の違いは別のブログで書きたいと思います。

ステータスが[保留中]から[成功]になったらOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/9f8c2135-65ae-b028-b92d-8c58bb8dcb76.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/3c206b03-3d7b-65df-9a74-f0427ad4ab35.png)



## 3. [部署アカウント]SSM Inventoryの「リソースデータの同期」を作成

[管理者アカウント]側で行った手順と同様に、リソースデータ同期を作成します。
リソースデータ同期名は任意の値で結構です。
S3バケットは手順1で作成したバケット名を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/49e6a25f-5b8a-5a52-0517-66a59121fbd7.png)


# 結果
こちらのように管理者アカウントのS3バケットにインベントリデータが集約されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/5cf41ae4-2f3c-37f2-2a25-ada53e0215f9.png)

AWSアカウントIDごとにオブジェクトが作成されていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/1c6b8d1e-823c-f391-d6f2-ce80add69b64.png)

インベントリ情報がjsonファイルでS3に出力されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/a33b4989-1cc2-4599-cc91-a2335da984f2.png)

管理者アカウントのSSMでも確認しましょう。
Systems Managerの[インベントリ]で[詳細ビュー]を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/99cb6389-32ed-0d8b-acc5-e11ffb56b7b8.png)

上記で作成したリソース同期を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/cc55dd94-64b1-59a8-e834-96b8a771c648.png)

ぐるぐるするのでチョット待ちます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/bbe2e5be-0678-62a2-abcb-65cdfae0b29b.png)


取れました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/0a97d922-13c3-6721-b189-e07f8440ba46.png)

プルダウンで好きなインベントリタイプを選択できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307047/20faa50c-9a2b-fa21-182d-3211b35189d9.png)


# なぜこんな簡単な手順のブログを書いたのか
上記の通り、簡単に設定が出来ました。

しかし __カスタムインベントリの取得を検証中に凄くトラブりました__ 。

恐らく何度もリソースデータ同期の作成・削除を繰り返したからだと思いますが、
根本原因として __SSM Inventoryの裏の仕組みを知らなかったから__ トラブルシュートできなかったのだと思います。

よって次回のブログでSSM Inventoryの裏の仕組みを解説します。