簡體   English   中英

為什么在 terraform 中創建的 S3 存儲桶需要存儲桶策略來授予對 lambda 的訪問權限

[英]Why does S3 bucket created in terraform needs bucket policy to grant access to lambda

我們使用雲形成和 terraform 的組合,其中一些常見資源(如 DynamoDB、S3)是使用 terraform 創建的,而其他資源(如 APIGateway)是使用無服務器和雲形成創建的。 所有資源都在同一個 AWS 賬戶中

我在 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]
  }
}

當我運行 tf-apply 時,這會在我的 AWS 賬戶中創建一個私有存儲桶payment-bucket-dev

我們在同一個 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/*

但是當我運行這個 lambda make-payment-dev時,它會引發 AccessDenied 錯誤,除非我添加存儲桶策略來授予對 lambda 角色的訪問權限

resource "aws_s3_bucket_policy" "payment_service_s3_bucket_policy" { 
..
..
}

當s3 bucket和lambda function和角色在同一個賬戶時,為什么我需要添加S3 bucket策略? 我錯過了什么嗎?

此外,如果我使用AWS::S3::Bucket作為 Apigateway 所在的雲形成堆棧的一部分創建了存儲桶(我們使用的是無服務器),我不需要添加存儲桶策略並且一切正常。

我認為問題只是 S3 存儲桶 ARN 不正確。

S3 存儲桶 ARN 中沒有賬戶 ID 或區域。 使用arn:aws:s3:::mybucket/myprefix/*

答案取決於 AWS IAM 角色應用 terraform 計划,因為 AWS s3 存儲桶罐裝 ACL 規則:“私有”將存儲桶訪問限制為:所有者獲得 FULL_CONTROL。 其他人沒有訪問權限(默認)。 每個文檔: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html

此時您必須相對明確地說明誰可以訪問存儲桶。 通常,如果我要使用私有 ACL,但希望我的 AWS 賬戶中的所有其他角色都可以訪問存儲桶,我會將存儲桶策略附加到 terraform aws_s3_bucket 資源,以首先允許訪問存儲桶。 然后我通過另一個內聯策略明確授予 lambda 角色訪問所述存儲桶的權限。

在您的情況下,它看起來像這樣:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM