はじめに
こんにちは、クマ松です。
SSM Inventoryについて、以前幾つか記事を書きました。
マルチアカウント構成でのSSM Inventoryによるインベントリ収集方法
今回はSSM Inventory機能を使って複数のAWSアカウントのインベントリ情報を集約する場合のS3バケットのポリシーの設定について、注意点を記載します。
複数アカウントのインベントリデータを集約する際のS3バケットポリシー
公式のドキュメントにS3バケットポリシーの例が記載されています。
AWS Systems Manager ユーザーガイドインベントリのリソースデータの同期の設定
この設定だと上手くいかないケースがあります。
AWS公式ドキュメントに記載されているポリシーは以下の通りです。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SSMBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::S3_bucket_name"
},
{
"Sid": " SSMBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::S3_bucket_name/*/accountid=ID_number/*",
"arn:aws:s3:::S3_bucket_name/*/accountid=ID_number/*",
"arn:aws:s3:::S3_bucket_name/*/accountid=ID_number/*",
"arn:aws:s3:::S3_bucket_name/*/accountid=ID_number/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control",
"aws:SourceAccount": "123456789012"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:ssm:*:123456789012:resource-data-sync/*"
}
}
}
]
}
こちらのバケットポリシーの中のSid:SSMBucketDeliveryについて解説すると
- 以下の条件が合致した場合(Condition)
- 特定の子アカウント(123456789012)からbucket-owner-full-control アクセスコントロールリスト (ACL)オプションが付与されているオブジェクト
- 特定の子アカウント(123456789012)のリソース同期からのインベントリ収集である
- 中央アカウントのS3内の、子アカウントIDのフォルダ毎に対して、
- インベントリ情報をputするためのPutObjectを実行できる
という意味になります。
子アカウントが1つの場合は上記の設定で問題ありません。
もし複数の子アカウントからインベントリを集約するためには、このS3バケットのポリシーの2か所を修正する必要があります。
- StringEquals
- ArnLike
複数AWSアカウントのSSMから、S3へインベントリデータをputできるよう、集合演算子 「ForAnyValue」 を利用します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SSMBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::S3_bucket_name"
},
{
"Sid": " SSMBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::S3_bucket_name/*/accountid=中央アカウントのAWSアカウントID/*",
"arn:aws:s3:::S3_bucket_name/*/accountid=子アカウントのAWSアカウントID/*",
"arn:aws:s3:::S3_bucket_name/*/accountid=子アカウントのAWSアカウントID/*",
"arn:aws:s3:::S3_bucket_name/*/accountid=子アカウントのAWSアカウントID/*"
],
"Condition": {
"ForAnyValue:StringEquals": { ←ココ
"aws:SourceAccount": [
"中央アカウントのAWSアカウントID",
"子アカウントのAWSアカウントID",
"子アカウントのAWSアカウントID",
"子アカウントの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:*:子アカウントのAWSアカウントID:resource-data-sync/*",
"arn:aws:ssm:*:子アカウントのAWSアカウントID:resource-data-sync/*",
"arn:aws:ssm:*:子アカウントのAWSアカウントID:resource-data-sync/*"
]
}
}
}
]
}
ForAnyValueを使うことで、複数の要素のうちどれか1つの要素の値が一致している場合に真になります。
複数の子アカウントからのインベントリデータを集約したい場合はこのように設定しましょう。