就上下文而言,我正在使用无服务器框架,因此发生了一些事情:
- 角色是使用一些附加策略创建的,并且 lambda 函数将其分配为执行角色。 S3 策略是(列出更多相关的策略):
ListBucket
将存储桶 ARN 作为资源GetObject
、PutObject
DeleteObjet
到存储桶 ARN 作为以/*
为前缀的资源
- 我使用 Cloudformation 资源语法创建存储桶,并设置了公共(public)读取策略,以便将其用作静态网站主机。
- 我还在 S3 存储桶策略中添加了另一个策略语句,我在其中分配写入操作并将执行角色 ARN 设置为主体。
我得到以下 iamRoleStatements
部分:
- Effect: "Allow"
Action:
- "s3:ListBucket"
Resource:
- Fn::Join:
- ""
- - "arn:aws:s3:::"
- Ref: StaticSiteBucket
- Effect: "Allow"
Action:
- "s3:GetObject"
- "s3:PutObject"
- "s3:DeleteObject"
- "s3:GetObjectVersionTagging"
- "s3:PutObjectVersionTagging"
Resource:
- Fn::Join:
- ""
- - "arn:aws:s3:::"
- Ref: StaticSiteBucket
- "/*"
我实际上可以确认它为生成的角色生成以下策略:
{
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket-name-here"
],
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:GetObjectVersionTagging",
"s3:PutObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::bucket-name-here/*"
],
"Effect": "Allow"
}
有了这个,我运行 lambda 函数来对该存储桶执行 putObject
。收到“访问被拒绝错误”
,所以我想如果存储桶本身需要允许写入怎么办,所以我在存储桶策略中包含了一条写入语句:
StaticSiteBucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: PublicRead
BucketName: ${self:service}-static-site-${self:provider.stage}
WebsiteConfiguration:
IndexDocument: index.html
StaticSiteBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: StaticSiteBucket
PolicyDocument:
Statement:
- Sid: PublicReadGetObject
Effect: Allow
Principal: "*"
Action:
- s3:GetObject
Resource:
Fn::Join: [
"", [
"arn:aws:s3:::",
{
"Ref": "StaticSiteBucket"
},
"/*"
]
]
- Sid: AllowLambdaRoleWrite
Effect: Allow
Action:
- "s3:GetObject"
- "s3:PutObject"
- "s3:DeleteObject"
- "s3:GetObjectVersionTagging"
- "s3:PutObjectVersionTagging"
Principal:
AWS:
- Fn::GetAtt: [ IamRoleLambdaExecution, Arn ]
Resource:
Fn::Join:
- ""
- - "arn:aws:s3:::"
- Ref: StaticSiteBucket
- "/*"
这会在 S3 存储桶中生成以下策略:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name-here/*"
},
{
"Sid": "AllowLambdaRoleWrite",
"Effect": "Allow",
"Principal": {
"AWS": "<role-arn>"
},
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:GetObjectVersionTagging",
"s3:PutObjectVersionTagging"
],
"Resource": "arn:aws:s3:::bucket-name-here/*"
}
]
}
所以,简而言之,我尝试过:
- 允许角色具有写入权限,但运气不佳
- 从存储桶策略向该角色附加写入权限,但不成功
我错过了什么?
最佳答案
所以就我而言,我缺少的是:
- 我必须包含
getObjectTagging
和putObjectTagging
操作。
对于任何有类似问题的人。请阅读下面的内容!
从教训中学习(我实际上花了一天半的时间在这上面)并意识到 Stackoverflow 是经验和知识的宝库。
我想指出:
- 确定您的代码正在执行哪些 API 操作,然后转到文档并进行检查。一些操作act on buckets而其他则在 objects
- 就我而言,我可以将任何其他政策声明放入存储桶中,换句话说,
- 执行角色是获得权力的角色。
- 我无法实现这一点,但如果有办法获得更明确的错误日志(至少在 aws-sdk 节点的库上),将节省大量时间。堆栈跟踪还不够。欢迎提出建议。
这就是我的 StaticSiteBucket 资源声明现在的样子:
- Effect: "Allow"
Action:
- "s3:ListBucket"
Resource:
- Fn::Join:
- ""
- - "arn:aws:s3:::"
- Ref: StaticSiteBucket
- Effect: "Allow"
Action:
- "s3:GetObject"
- "s3:PutObject"
- "s3:DeleteObject"
- "s3:GetObjectTagging"
- "s3:PutObjectTagging"
Resource:
- Fn::Join:
- ""
- - "arn:aws:s3:::"
- Ref: StaticSiteBucket
- "/*"
关于amazon-s3 - 如何正确设置 IAM 执行角色和存储桶策略以将 lambda 写入公共(public)读取 S3 存储桶?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56088468/