kinesis-firehoseでクロスアカウントのs3バケットデータを保存する

前提

デリバリーストリームと同一アカウント内のs3バケットへの保存はできている。 環境分離の観点などから他アカウントのバケットへ保存したくなった時の方法

配信先のバケットバケットポリシー

docs.aws.amazon.com

{

    "Version": "2012-10-17",
    "Id": "PolicyID",
    "Statement": [
        {
            "Sid": "StmtID",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::accountA-id:role/iam-role-name"
            },
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-name",
                "arn:aws:s3:::bucket-name/*"
            ]
        }
    ]
}

バケットポリシーを設定してaccountAのデリバリーストリームに付与されているRoleからの書き込みを許可する

ここ

 "AWS": "arn:aws:iam::accountA-id:role/iam-role-name"

firehoseのIAM Roleを変更する

docs.aws.amazon.com

{
    "Version": "2012-10-17",  
    "Statement":
    [    
        {      
            "Effect": "Allow",      
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject"
            ],      
            "Resource": [        
                "arn:aws:s3:::bucket-name",
                "arn:aws:s3:::bucket-name/*"            
            ]    
        },        
        {
            "Effect": "Allow",
            "Action": [
                "kinesis:DescribeStream",
                "kinesis:GetShardIterator",
                "kinesis:GetRecords",
                "kinesis:ListShards"
            ],
            "Resource": "arn:aws:kinesis:region:account-id:stream/stream-name"
        },
        {
           "Effect": "Allow",
           "Action": [
               "kms:Decrypt",
               "kms:GenerateDataKey"
           ],
           "Resource": [
               "arn:aws:kms:region:account-id:key/key-id"           
           ],
           "Condition": {
               "StringEquals": {
                   "kms:ViaService": "s3.region.amazonaws.com"
               },
               "StringLike": {
                   "kms:EncryptionContext:aws:s3:arn": "arn:aws:s3:::bucket-name/prefix*"
               }
           }
        },
        {
           "Effect": "Allow",
           "Action": [
               "logs:PutLogEvents"
           ],
           "Resource": [
               "arn:aws:logs:region:account-id:log-group:log-group-name:log-stream:log-stream-name"
           ]
        },
        {
           "Effect": "Allow", 
           "Action": [
               "lambda:InvokeFunction", 
               "lambda:GetFunctionConfiguration" 
           ],
           "Resource": [
               "arn:aws:lambda:region:account-id:function:function-name:function-version"
           ]
        }
    ]
}

前提乗っ取るとすでにIAM Roleが付与されているので、

                "arn:aws:s3:::bucket-name",
"arn:aws:s3:::bucket-name/*",

ここのバケットを追加していく。

忘れがちな注意点

docs.aws.amazon.com

S3 バケットを所有していない場合、Amazon S3 アクションのリストに s3:PutObjectAcl を追加します。これにより、Kinesis Data Firehose で配信されるオブジェクトへのフルアクセスが、バケット所有者に付与されます。

上記のfirehoseが使用するIAM Roleに付与しておく。そのため

                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject",
                "s3:PutObjectAcl"

こうなる

デリバリーストリームに配信先を変更するよう設定変更する

コンソールからはクロスアカウントのs3が指定できないためcliで行う。 事前準備として VersionId と DestinationId が必要なため取得しておく

aws firehose describe-delivery-stream --delivery-stream-name ストリームネーム | jq .DeliveryStreamDescription.VersionId
aws firehose describe-delivery-stream --delivery-stream-name ストリームネーム | jq '.DeliveryStreamDescription.Destinations[].DestinationId'

戻り値から取得しておく

aws firehose update-destination --delivery-stream-name ストリームネーム --current-delivery-stream-version-id 取得した値 --destination-id 取得した値 --s3-destination-update BucketARN=arn:aws:s3:::クロスアカウントのバケット名

firehoseのエラーが出てないこととs3バケットにデータが来ていることが確認できたら成功