如何通过CloudFormation配置S3终端节点,仅通过S3桶策略授权指定Lambda函数访问S3
解决Lambda通过S3桶策略访问特定存储桶的权限问题
我帮你梳理下问题所在,以及对应的解决方案:
核心问题分析
你直接把Lambda函数的ARN设为S3桶策略的Principal是行不通的——因为Lambda执行时,是使用它的执行角色(Execution Role)的身份来发起S3请求的,而不是Lambda函数本身的ARN。这就是为什么设*能正常工作,但指定Lambda ARN不行的原因。
同时你的S3 VPC端点策略当前用了Principal: "*",这也会放大权限范围,需要同步收紧。
方案一:通过Lambda执行角色+源ARN限定权限(推荐)
这种方式既严格限定了允许访问的身份(Lambda执行角色),又确保请求确实来自目标Lambda函数,安全性最高。
修正后的S3桶策略
S3: Type: AWS::S3::Bucket Properties: BucketName: "some-random-bucket" S3BucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: S3 Properties: Bucket: !Ref S3 PolicyDocument: Version: 2012-10-17 Statement: - Action: 's3:PutObject' Effect: Allow # 用!Sub动态生成资源ARN,避免硬编码 Resource: !Sub "${S3.Arn}/*" # 指定Lambda的执行角色ARN作为Principal Principal: AWS: !GetAtt LambdaExecutionRole.Arn # 添加条件,确保请求来自目标Lambda函数 Condition: StringEquals: aws:SourceArn: !GetAtt LambdaFunction.Arn
修正后的S3 VPC端点策略
S3Endpoint: Type: AWS::EC2::VPCEndpoint Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: !GetAtt LambdaExecutionRole.Arn Action: "s3:PutObject" Resource: !Sub "${S3.Arn}/*" # 同样添加源ARN条件,收紧VPC端点的访问权限 Condition: StringEquals: aws:SourceArn: !GetAtt LambdaFunction.Arn ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3' VpcId: !Ref VPC
关键注意事项
- 确保你的Lambda函数已经关联了
LambdaExecutionRole(需要在模板中定义这个IAM角色,且角色没有被附加拒绝S3访问的策略) - 确认Lambda部署在VPC的私有子网中,且子网的路由表已经配置指向S3 VPC端点
- 不要硬编码ARN,用CloudFormation的内置函数(
!GetAtt、!Sub)动态生成,避免跨区域/账号的配置错误 - 如果你的Lambda需要其他S3操作(比如
ListBucket),记得在策略的Action字段中添加对应的权限
备选方案:仅用Lambda执行角色作为Principal
如果你不需要额外限定请求源,也可以只把Lambda执行角色ARN设为Principal,但这种方式下,如果该执行角色被其他资源使用,也能访问这个S3桶,安全性稍弱:
# 桶策略示例片段 Statement: - Action: 's3:PutObject' Effect: Allow Resource: !Sub "${S3.Arn}/*" Principal: AWS: !GetAtt LambdaExecutionRole.Arn
内容的提问来源于stack exchange,提问作者KoalaKey
相关产品推荐
相关产品推荐

