Lambda で AssumeRole を実行後に別アカウントの S3 バケットへアクセスしたのですが、アクセス拒否されたので解決策を教えてください

2022.09.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

困っていた内容

Lambda で 2 つの AWS アカウントにある S3 バケットの内容をコピーしようと考えています。
要件上、Lambda で AssumeRole を実行してから、別アカウントの S3 バケットにアクセスする必要があるのですが、AssumeRole 実行後に別アカウントの S3 バケットへのアクセスが拒否されました。
別アカウントの S3 バケットポリシーでは、Lambda の実行ロールからのアクセスを許可していますが、エラーが解消されません。

Lambda で AssumeRole を実行後に別アカウントの S3 バケットへアクセスした際、アクセス拒否された理由と解決策を教えてください。

どう対応すればいいの?

別アカウントの S3 バケットポリシーに、AssumeRole で引き受ける IAM ロールの ARN を指定してください。
Lambda で AssumeRole を実行せずに S3 バケットへアクセスする場合には、S3 バケットポリシーに Lambda の実行ロールを指定します。
一方、AssumeRole を実行した場合、S3 バケットへアクセスするのは、AssumeRole で引き受けた IAM ロールです。

そのため、別アカウントの S3 バケットポリシーで、AssumeRole で引き受ける IAM ロールからのアクセスを許可してください。

参考ではありますが、以下のようなバケットポリシーを指定します。

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
        { 
            "Sid": "Sample-Bucuket-Policy", 
            "Effect": "Allow", 
            "Principal": { 
                "AWS": "arn:aws:iam::{account-id}:role/{role-name}" 
            }, 
            "Action": [ 
                "s3:ListBucket", 
                "s3:GetObject", 
                "s3:PutObject", 
                "s3:DeleteObject" 
            ], 
            "Resource": [ 
                "arn:aws:s3:::{bucket-name}", 
                "arn:aws:s3:::{bucket-name}/*" 
            ] 
        } 
    ] 
}

ポイントは、Principal の部分に AssumeRole で引き受ける IAM ロールの ARN を指定することです。
Action や Resource は適宜調整してください。

参考資料