简体   繁体   English

为什么在 terraform 中创建的 S3 存储桶需要存储桶策略来授予对 lambda 的访问权限

[英]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 importhttps://github.com/hashicorp/terraform-provider-aws/issues/6193

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 S3 存储桶策略授予/限制对特定联合用户的访问权限 - S3 bucket policy to grant/restrict access to a specific federated user 使用存储桶策略限制 S3 存储桶访问 - S3 bucket access restriction with bucket policy Terraform对S3存储桶使用现有策略 - Terraform use existing policy for s3 bucket 如何使用简单的 s3 存储桶策略授予对加密存储桶的跨账户访问权限? - How do I grant cross account access to an encrypted bucket with a simple s3 bucket policy? 在S3中仅授予对一个存储桶的访问权限 - Grant access to only one bucket in S3 为什么我的 S3 存储桶策略拒绝跨账户访问? - Why is my S3 bucket policy denying cross account access? 为什么terraform会在s3桶里创建一个空目录? - Why does terraform create an empty directory in the s3 bucket? 为什么存储桶策略不提供 IAM 用户列出 s3 存储桶,即使为用户设置了存储桶策略? - Why bucket policy does not provide IAM user to list s3 buckets even bucket policy is set for the user? Terraform InvalidConfigurationRequest:S3 存储桶的访问被拒绝 - Terraform InvalidConfigurationRequest: Access denied for S3 bucket 为什么我的 lambda function 在尝试访问 S3 存储桶时访问被拒绝? - Why does my lambda function get Access Denied trying to access an S3 bucket?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM