[AWS] Lambda で S3 バケットに対する権限を CDK Python で付与したい
はじめに
Lambda から S3 バケットに対して Read/Write したいけどバケットを Public にするわけにはいかない。
そんなときはバケットポリシーで特定の Lambda に対してのみ Read/Write 権限を付与しましょう。
CDK Python でやるときはこんな感じになります。
サンプル
from aws_cdk import (core, aws_s3, aws_iam, ) from aws_cdk.aws_lambda import Runtime from aws_cdk.aws_lambda_python import PythonFunction class SampleStack(core.Stack): def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # lambda lambda_ = PythonFunction( self, 'SampleLambda', runtime=Runtime.PYTHON_3_8, entry='src', index='sample.py', handler='handler') # S3 bucket_ = aws_s3.Bucket(self, 'sample-bucket-name') bucket_.add_to_resource_policy( aws_iam.PolicyStatement( effect=aws_iam.Effect.ALLOW, actions=['s3:PutObject', 's3:GetObject'], principals=[ aws_iam.ArnPrincipal( lambda_.role.role_arn ) ], resources=[ bucket_.arn_for_objects('*') ] ) )
こちらをデプロイすると S3 のバケットポリシーは以下のようになります。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": ["{Lambda Role ARN}"] }, "Action": ["s3:PutObject", "s3:GetObject"], "Resource": "{S3 Bucket ARN}/*" } ] }
これで対象の Lambda 以外からは Access Denied を返すようになりました。
サンプルでは Put と Get 両方付与していますが、S3 バケットから読み取りのみ行う Lambda であれば Action には s3:GetObject
のみ設定してください。
おわりに
ArnPrincipal を使うことで "AWS": ["{ARN}"]
の書き方ができます。
Lambda だけでなく特定ユーザーのみ操作できるようにするといった場合は IAM ユーザー ARN を設定すればよさそうです。
S3 バケット名は全世界でユニークなので公開は極力控えていきましょう。