Amazon web services 为什么在terraform中创建的S3 bucket需要bucket策略来授予对lambda的访问权限
我们使用云形成和terraform的组合,其中一些常见资源(如DynamoDB、S3)使用terraform创建,其他资源(如APIGateway)使用无服务器和云形成创建。所有资源都在同一AWS帐户中 我有一个地形的S3水桶Amazon web services 为什么在terraform中创建的S3 bucket需要bucket策略来授予对lambda的访问权限,amazon-web-services,amazon-s3,aws-lambda,terraform,aws-api-gateway,Amazon Web Services,Amazon S3,Aws Lambda,Terraform,Aws Api Gateway,我们使用云形成和terraform的组合,其中一些常见资源(如DynamoDB、S3)使用terraform创建,其他资源(如APIGateway)使用无服务器和云形成创建。所有资源都在同一AWS帐户中 我有一个地形的S3水桶 resource "aws_s3_bucket" "payment_bucket" { bucket = "payment-bucket-${var.env_name}" acl = "private" tags = merge( module
resource "aws_s3_bucket" "payment_bucket" {
bucket = "payment-bucket-${var.env_name}"
acl = "private"
tags = merge(
module.tags.base_tags,
{
"Name" = "payment-bucket-${var.env_name}"
}
)
lifecycle {
ignore_changes = [tags]
}
}
当我运行tf apply时,这将在我的AWS帐户中创建一个私有bucket支付bucket dev
我们在使用serverless创建的同一AWS帐户中有一个APIGateway,其中一个lambda需要访问该bucket,因此我为lambda函数创建了一个IAM角色,以授予访问该bucket的权限
makePayment:
name: makePayment-${self:provider.stage}
handler: src/handler/makePayment.default
events:
- http:
path: /payment
method: post
private: true
cors: true
iamRoleStatementsName: ${self:service}-${self:provider.stage}-makePayment-role
iamRoleStatements:
- Effect: Allow
Action:
- s3:PutObject
Resource:
- arn:aws:s3:::#{AWS::Region}:#{AWS::AccountId}:payment-bucket-${self:provider.stage}/capture/batch/*
但是,当我运行这个lambdamakepayment dev
时,它会抛出一个AccessDenied错误,除非我添加授予lambda角色访问权限的bucket策略
resource "aws_s3_bucket_policy" "payment_service_s3_bucket_policy" {
..
..
}
当S3 bucket和lambda函数和角色在同一个帐户中时,为什么我需要添加S3 bucket策略?我错过什么了吗
另外,如果我使用
AWS::S3::bucket
创建了bucket,作为Apigateway所在的云形成堆栈的一部分(我们使用的是无服务器),我不需要添加bucket策略,而且一切正常。我认为问题在于S3 bucket ARN不正确
S3 bucket ARN中没有帐户ID或区域。使用
arn:aws:s3:::mybucket/myprefix/*
我认为问题在于s3 bucket arn不正确
S3 bucket ARN中没有帐户ID或区域。使用
arn:aws:s3:::mybucket/myprefix/*
答案取决于应用地形平面图的aws IAM角色,因为aws s3 bucket-canted ACL规则:“private”限制bucket访问,因为:Owner获得完全控制权。其他人没有访问权限(默认)。根据文件:
在这一点上,您必须相对明确谁可以访问bucket。通常,如果我使用私有ACL,但希望AWS帐户中的每个其他角色都能访问bucket,我会将bucket策略附加到terraform AWS_s3_bucket资源,以首先允许访问bucket。然后,我通过另一个内联策略显式地授予lambda角色对所述bucket的访问权
在您的情况下,它看起来像这样:
// Allow access to the bucket
data "aws_iam_policy_document" "bucket_policy" {
statement {
sid = "S3 bucket policy for account access"
actions = [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::{your_account_id_here}:root",
]
}
resources = [
"arn:aws:s3:::test_bucket_name",
"arn:aws:s3:::test_bucket_name/*",
]
condition {
test = "StringEquals"
variable = "aws:PrincipalArn"
values = ["arn:aws:iam::{your_account_id_here}:role/*"]
}
}
}
resource "aws_s3_bucket" "this" {
bucket = "test_bucket_name"
acl = "private"
policy = data.aws_iam_policy_document.bucket_policy.json
}
// Grant the lambda IAM role permissions to the bucket
data "aws_iam_policy_document" "grant_bucket_access" {
statement {
sid = "AccessToTheAppAuxFilesBucket"
actions = [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
resources = [
"arn:aws:s3:::test_bucket_name/*",
"arn:aws:s3:::test_bucket_name"
]
}
}
// Data call to pull the arn of the lambda's IAM Role
data "aws_iam_role" "cloudformation_provisioned_role" {
name = "the_name_of_the_lambdas_iam_role"
}
resource "aws_iam_role_policy" "iam_role_inline_policy" {
name = "s3_bucket_access"
role = data.aws_iam_role.cloudformation_provisioned_role.arn
policy = data.aws_iam_policy_document.grant_bucket_access.json
}
答案取决于AWS IAM角色在应用terraform plan时扮演的角色,因为AWS s3 bucket canned ACL规则:“private”限制bucket访问,因为:Owner获得完全控制权。其他人没有访问权限(默认)。根据文件: 在这一点上,您必须相对明确谁可以访问bucket。通常,如果我使用私有ACL,但希望AWS帐户中的每个其他角色都能访问bucket,我会将bucket策略附加到terraform AWS_s3_bucket资源,以首先允许访问bucket。然后,我通过另一个内联策略显式地授予lambda角色对所述bucket的访问权 在您的情况下,它看起来像这样:
// Allow access to the bucket
data "aws_iam_policy_document" "bucket_policy" {
statement {
sid = "S3 bucket policy for account access"
actions = [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::{your_account_id_here}:root",
]
}
resources = [
"arn:aws:s3:::test_bucket_name",
"arn:aws:s3:::test_bucket_name/*",
]
condition {
test = "StringEquals"
variable = "aws:PrincipalArn"
values = ["arn:aws:iam::{your_account_id_here}:role/*"]
}
}
}
resource "aws_s3_bucket" "this" {
bucket = "test_bucket_name"
acl = "private"
policy = data.aws_iam_policy_document.bucket_policy.json
}
// Grant the lambda IAM role permissions to the bucket
data "aws_iam_policy_document" "grant_bucket_access" {
statement {
sid = "AccessToTheAppAuxFilesBucket"
actions = [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
resources = [
"arn:aws:s3:::test_bucket_name/*",
"arn:aws:s3:::test_bucket_name"
]
}
}
// Data call to pull the arn of the lambda's IAM Role
data "aws_iam_role" "cloudformation_provisioned_role" {
name = "the_name_of_the_lambdas_iam_role"
}
resource "aws_iam_role_policy" "iam_role_inline_policy" {
name = "s3_bucket_access"
role = data.aws_iam_role.cloudformation_provisioned_role.arn
policy = data.aws_iam_policy_document.grant_bucket_access.json
}
这是一个公开的错误。acl和force_destroy在terraform导入时没有很好地导入:这是一个开放的bug。acl和force_destroy不能很好地与terraform导入一起导入。:S3 bucket ARN中没有帐户ID或区域。使用
arn:aws:s3:::mybucket/myprefix/*
。谢谢!这解决了问题。S3 bucket ARN中没有帐户ID或区域。使用arn:aws:s3:::mybucket/myprefix/*
。谢谢!这解决了问题。