[英]Why does S3 bucket created in terraform needs bucket policy to grant access to lambda
We use a combination of cloud formation and terraform where some common resources like DynamoDB, S3 are created using terraform and others like APIGateway are created using serverless and cloudformation.我们使用云形成和 terraform 的组合,其中一些常见资源(如 DynamoDB、S3)是使用 terraform 创建的,而其他资源(如 APIGateway)是使用无服务器和云形成创建的。 All resources are in the same AWS account
所有资源都在同一个 AWS 账户中
I have an S3 bucket in terraform我在 terraform 中有一个 S3 存储桶
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]
}
}
This creates a private bucket payment-bucket-dev
in my AWS account when I run the tf-apply当我运行 tf-apply 时,这会在我的 AWS 账户中创建一个私有存储桶
payment-bucket-dev
We have an APIGateway in the same AWS account which is created using serverless and one of the lambda needs accesses to this bucket so I have created an IAM role for the lambda function to grant permission to access the bucket.我们在同一个 AWS 账户中有一个 APIGateway,它是使用无服务器创建的,其中一个 lambda 需要访问此存储桶,因此我为 lambda ZC1C425268E68385D1AB504C1 授予访问权限 74C1A 存储桶的 IAM 角色。
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/*
But when I run this lambda make-payment-dev
, it throws an AccessDenied error unless I add bucket policy granting access to the lambda role但是当我运行这个 lambda
make-payment-dev
时,它会引发 AccessDenied 错误,除非我添加存储桶策略来授予对 lambda 角色的访问权限
resource "aws_s3_bucket_policy" "payment_service_s3_bucket_policy" {
..
..
}
Why do I need to add S3 bucket policy when both s3 bucket and the lambda function and role are in the same account?当s3 bucket和lambda function和角色在同一个账户时,为什么我需要添加S3 bucket策略? Am I missing something?
我错过了什么吗?
Also, If I created the bucket using AWS::S3::Bucket
as part of the cloud formation stack the Apigateway is in (we are using serverless), I don't need add bucket policy and it all works fine.此外,如果我使用
AWS::S3::Bucket
作为 Apigateway 所在的云形成堆栈的一部分创建了存储桶(我们使用的是无服务器),我不需要添加存储桶策略并且一切正常。
I think the problem is simply that the S3 bucket ARN is incorrect.我认为问题只是 S3 存储桶 ARN 不正确。
S3 bucket ARNs do not have account IDs or regions in them. S3 存储桶 ARN 中没有账户 ID 或区域。 Use
arn:aws:s3:::mybucket/myprefix/*
.使用
arn:aws:s3:::mybucket/myprefix/*
。
The answer depends on what AWS IAM role is applying the terraform plan because the AWS s3 bucket canned ACL rule: "private" restricts bucket access as: Owner gets FULL_CONTROL.答案取决于 AWS IAM 角色应用 terraform 计划,因为 AWS s3 存储桶罐装 ACL 规则:“私有”将存储桶访问限制为:所有者获得 FULL_CONTROL。 No one else has access rights (default).
其他人没有访问权限(默认)。 per documentation: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html
每个文档: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html
You have to be relatively explicit at this point as to who can access the bucket.此时您必须相对明确地说明谁可以访问存储桶。 Often if I'm going with private ACL but want every other role in my AWS account to have access to the bucket I attach a bucket policy to the terraform aws_s3_bucket resource to first allow access to the bucket.
通常,如果我要使用私有 ACL,但希望我的 AWS 账户中的所有其他角色都可以访问存储桶,我会将存储桶策略附加到 terraform aws_s3_bucket 资源,以首先允许访问存储桶。 Then I explicitly grant the lambda's role access to said bucket via another inline policy.
然后我通过另一个内联策略明确授予 lambda 角色访问所述存储桶的权限。
In your case it would look something like this:在您的情况下,它看起来像这样:
// 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
}
It's an open bug.这是一个开放的错误。 acl and force_destroy aren't well imported with
terraform import
:https://github.com/hashicorp/terraform-provider-aws/issues/6193 acl 和 force_destroy 不能很好地使用
terraform import
:https://github.com/hashicorp/terraform-provider-aws/issues/6193
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.