【发布时间】:2021-03-30 20:20:28
【问题描述】:
CDK 问题总是很难问。我有一个 s3 存储桶和一个云端 CDN 来提供服务。还有一个 Lambda 函数运行代码以将文件放入存储桶中,但 lambda 日志在尝试写入时报告 ERROR AccessDenied: Access Denied at Request.extractError。
如何允许我的 lambda 进程访问存储桶,但防止来自云端的未经授权的访问?
我无法在不混淆的情况下分享我的 CDK 代码,但这里是它的要点:
const myBucket = new s3.Bucket(this, `CDNBucket`, {
bucketName: `mybucketname`,
publicReadAccess: false
})
const originAccessIdentity = new cloudfront.OriginAccessIdentity(scope, 'CDNIdentity')
const myBucketPolicy = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['s3:GetObject'],
principals: [
new iam.CanonicalUserPrincipal(
originAccessIdentity.cloudFrontOriginAccessIdentityS3CanonicalUserId
)
],
resources: [myBucket.bucketArn + '/*']
})
myBucket.addToResourcePolicy(myBucketPolicy)
const lambdaWatcher = new lambda.Function(this, `MyFunctionName`, {
code: new lambda.AssetCode(lambdaNodePath),
functionName: 'MyFunctionName',
handler: 'lambda.handler',
runtime: lambda.Runtime.NODEJS_12_X,
})
props.buckets.myBucket.grantReadWrite(this.lambdaWatcher)
const cloudFrontWebDistribution = new cloudfront.CloudFrontWebDistribution(
this,
`Web_CDN`,
{
comment: `CDN distribution`,
originConfigs: [
{
s3OriginSource: {
s3BucketSource: myBucket,
originAccessIdentity: originAccessIdentity
},
behaviors: [
{
isDefaultBehavior: true,
compress: true,
minTtl: cdk.Duration.seconds(0),
maxTtl: cdk.Duration.days(365),
defaultTtl: cdk.Duration.days(1)
}
]
}
]
}
)
生成的桶策略是:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXXXXXXXXXXX"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucketname/*"
}
]
}
而生成的 Lambda 策略是:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
"s3:DeleteObject*",
"s3:PutObject",
"s3:Abort*"
],
"Resource": [
"arn:aws:s3:::mybucketname",
"arn:aws:s3:::mybucketname/*"
],
"Effect": "Allow"
},
]
}
【问题讨论】:
标签: amazon-web-services aws-cdk