SSMのログを別AWSアカウントS3に送る方法

2021.08.03

テクニカルサポートチームの丸屋 正志(Maruya Masashi)です。

困っていた内容

SSM の実行ログを別 AWS アカウントの S3 バケットに出力したいのですが、どうしたら良いでしょうか?

また、複数の送信元 AWS アカウントからも SSM のログを送信したいです。

どう対応すればいいの?

送信元 AWS アカウントにて、IAM ロールの作成と SSM の送信元の設定が必要です。

そして、受信先 AWS アカウントにて、受信先にて S3 バケットポリシーの設定も必要となります。

やってみた

事前に受信先の S3 バケットをデフォルト設定で作成しておきます。

各種ロール名やバケット名については、任意のものが指定できますが、今回はサンプルとして以下のを前提といたします。

  • 受信先バケット名 : exam-01
  • プレフィックス:AWSLogs
  • ロール名 : EC2-SSM

送信元AWSアカウントにて

SSM の IAM ロール作成については、こちらの Blog をご参照くださいませ。

上記 Blog の『ステップ 2 にて』を参考にロールを作成時に、AmazonSSMManagedInstanceCore のみをアタッチします。
その後に作成後にインラインポリシーとして、下記ポリシーを追加します。

SSM のログを別アカウントのバケットに送信するため、明示的に受信先バケット名を指定する必要があります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObjectAcl",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::受信先バケット名/プレフィックス/*"
            ]
        }
    ]
}

変更後の例

Image from Gyazo

System Manager編』まで進めて頂き、『Choose S3 bucket』箇所にて下記のように変更致します。

  • 【テキストボックスにバケット名を入力する】を選択
  • 受信先のバケット名(例 : exam-01)を入力

Image from Gyazo

保存後、受信先のバケット名(例 : exam-01)になっていることを確認

Image from Gyazo

受信先AWSアカウントにて

S3 バケットポリシーを下記のように変更いたします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWS_SSM_Delivery",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::送信元AWSアカウントID:role/ロール名"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::受信先バケット名/プレフィックス/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

補足1 : 複数のアカウントの場合

もし複数の送信元 AWS アカウントから SSM データを送信する場合は、受信先 AWS アカウントのバケットポリシーの Principal 句を下記の様に変更すると実現が可能です。
但し、事前に各送信元 AWS アカウントにてロールを作成しておく必要があります。

"Principal": {
                "Service": "ssm.amazonaws.com",
                "AWS": [
                  "arn:aws:iam::送信元AWSアカウントID-A:role/ロール名",
                  "arn:aws:iam::送信元AWSアカウントID-B:role/ロール名",
                  "arn:aws:iam::送信元AWSアカウントID-C:role/ロール名"
                ]
            },

また、現在は全て バケット名/プレフィックス/ の直下にファイルが書き込まれますが、これでは管理が大変です。
送信元 AWS アカウント毎に出力先を別けたい場合は、送信元 AWS アカウントの SSM の設定画面の 『S3 Logging』欄の『S3 のキープレフィックス - オプション』にて プレフィックス/送信元AWSアカウントID-A と記述してあげると管理がしやすくなります。

Image from Gyazo

補足2 : Enforce encryptionが有効化されていた場合

SSM 設定の 『Enforce encryption』を有効化していた場合については、追加のポリシー設定が必要となります。

Image from Gyazo

送信元 AWS アカウントの作成したIAM ロール(EC2-SSM)のインラインポリシーにて、下記ポリシーのように書き換えます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObjectAcl",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::受信先バケット名/プレフィックス/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetEncryptionConfiguration"
            ],
            "Resource": "arn:aws:s3:::受信先バケット名"
        }
    ]
}

受信先 AWS アカウントの S3 バケットポリシーにを下記のように変更致します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWS_SSM_Delivery",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::送信元AWSアカウントID:role/ロール名"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::受信先バケット名/プレフィックス/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::送信元AWSアカウントID:role/ロール名"
            },
            "Action": "s3:GetEncryptionConfiguration",
            "Resource": "arn:aws:s3:::受信先バケット名"
        }
    ]
}

トラブルシューティング

下記のようなエラーが発生した場合については、こちらの手順を確認してみてください。

接続エラー UserName-InstanceID

セッションが次の理由で終了されました。 Couldn't start the session because we are unable to validate encryption on Amazon S3 bucket. Error: AccessDenied: Access Denied status code: 403, request id: 一意のID , host id: 一意のID

Image from Gyazo

送信元 AWS アカウントの SSM 設定『S3 logging』の欄を確認し【Enforce S3 log encryption】が【YES】になっていた場合は、【No】に変更します。

Image from Gyazo

参考資料