Lambda通过S3网关VPCEndpoint上传对象时策略验证失败排查
问题描述
我有一个部署在无NAT网关的公有子网中的Lambda函数,需要向S3存储桶执行PutObject操作。为此创建了网关类型的VPC端点,配置如下:
UploadsBucketS3GatewayEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: "*" Action: - s3:PutObject Resource: - !Sub 'arn:aws:s3:::${UploadsBucket}' - !Sub 'arn:aws:s3:::${UploadsBucket}/*' RouteTableIds: - ${cf:vpc.PublicRouteTable} ServiceName: com.amazonaws.${self:provider.region}.s3 VpcId: ${cf:vpc.VpcId}
部署时收到错误提示:
Please provide a valid VPC Endpoint policy (Service: Ec2, Status Code: 400, Request ID: xx)
请问我的VPC端点配置存在什么问题?
附加信息
以下是存储桶完整的CloudFormation配置(位于Serverless Framework的resources部分):
Resources: UploadsBucket: Type: AWS::S3::Bucket Properties: BucketName: redacted-website-name-uploads-${opt:stage} AccessControl: Private UploadsBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref UploadsBucket PolicyDocument: Statement: - Sid: AllowGetFromCloudfront Effect: Allow Action: s3:GetObject Resource: !Sub 'arn:aws:s3:::${UploadsBucket}/*' Principal: AWS: - !Sub "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${UploadsDistributionOAI.Id}" - Sid: AllowAdministrationFromVpcEndpoint Effect: Allow Action: s3:* Resource: !Sub 'arn:aws:s3:::${UploadsBucket}/*' Principal: "*" Condition: StringEquals: aws:userid: - !Ref UploadsBucketS3GatewayEndpoint UploadsDistributionOAI: Type: AWS::CloudFront::CloudFrontOriginAccessIdentity Properties: CloudFrontOriginAccessIdentityConfig: Comment: 'OAI for CloudFront access to s3' UploadsDistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Comment: PWB uploads Origins: - DomainName: !GetAtt UploadsBucket.RegionalDomainName Id: 's3-origin' S3OriginConfig: OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${UploadsDistributionOAI.Id}" PriceClass: PriceClass_100 Enabled: true DefaultCacheBehavior: TargetOriginId: 's3-origin' ViewerProtocolPolicy: 'redirect-to-https' ForwardedValues: QueryString: 'false' Cookies: Forward: all # This enables lambda to talk to the uploads bucket without needing a NAT gateway UploadsBucketS3GatewayEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: "*" Action: - s3:PutObject Resource: - !Sub 'arn:aws:s3:::${UploadsBucket}' - !Sub 'arn:aws:s3:::${UploadsBucket}/*' RouteTableIds: - ${cf:vpc.PublicRouteTable} ServiceName: com.amazonaws.${self:provider.region}.s3 VpcId: ${cf:vpc.VpcId}
问题分析与解决方案
核心错误原因
- S3网关型VPC端点策略不允许通配符Principal:AWS对S3网关端点的策略有严格限制,
Principal字段不能直接设为"*",必须指定具体IAM身份(如Lambda执行角色ARN),或通过条件限制访问来源。 - 资源声明冗余:
s3:PutObject操作的目标是存储桶内的对象,而非存储桶本身,策略中包含arn:aws:s3:::${UploadsBucket}属于无效资源声明,会触发策略校验失败。
修正后的VPC端点策略
方案1:指定Lambda执行角色作为Principal
直接授权Lambda的执行角色通过端点访问S3:
PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: - !GetAtt LambdaExecutionRole.Arn # 替换为你的Lambda执行角色ARN Action: - s3:PutObject Resource: - !Sub 'arn:aws:s3:::${UploadsBucket}/*'
方案2:通过条件限制访问来源
如果需要开放端点给VPC内所有符合条件的身份,可通过VPC或端点ID限制:
PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: "*" Action: - s3:PutObject Resource: - !Sub 'arn:aws:s3:::${UploadsBucket}/*' Condition: StringEquals: aws:SourceVpce: !Ref UploadsBucketS3GatewayEndpoint # 限制仅通过当前端点访问
额外注意事项
- Lambda执行角色本身必须拥有
s3:PutObject权限,VPC端点策略是附加访问控制层,无法替代IAM角色权限。 - 公有子网的路由表已关联VPC端点,这部分配置正确,能确保Lambda通过端点访问S3而非公网。
- 存储桶策略中用
aws:userid关联VPC端点ID的方式可行,注意VPC端点的userid格式为vpce-xxxxxx,引用需正确。
内容的提问来源于stack exchange,提问作者amacrobert
相关产品推荐
相关产品推荐

