Почему корзине S3, созданной в terraform, нужна политика корзины для предоставления доступа к лямбда - PullRequest
0 голосов
/ 06 мая 2020

Мы используем комбинацию формирования облака и терраформирования, при этом некоторые общие ресурсы, такие как DynamoDB, S3, создаются с использованием terraform, а другие, такие как APIGateway, создаются с использованием бессерверной и облачной информации. Все ресурсы находятся в одной учетной записи AWS

У меня есть корзина 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]
  }
}

Это создает частную корзину payment-bucket-dev в моей учетной записи AWS, когда я запускаю tf-apply

У нас есть APIGateway в той же учетной записи AWS, которая создается без сервера, и одной из лямбда-выражений требуется доступ к этому ведру, поэтому я создал роль 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/*

Но когда я запускаю эту лямбда make-payment-dev, она выдает ошибку AccessDenied, если я не добавлю политику корзины, предоставляющую доступ к лямбда-роли

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

Почему Мне нужно добавить политику корзины S3, когда и корзина s3, и лямбда-функция, и роль находятся в одной учетной записи? Я что-то упустил?

Кроме того, если я создал ведро, используя AWS::S3::Bucket как часть стека формирования облака, в котором находится Apigateway (мы используем бессерверную версию), мне не нужно добавлять политику ведра, и это все работает нормально.

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Я думаю, проблема заключается просто в том, что ARN корзины S3 неверен.

ARN корзины S3 не имеют идентификаторов учетных записей или регионов. Используйте arn:aws:s3:::mybucket/myprefix/*.

0 голосов
/ 06 мая 2020

Ответ зависит от того, какая AWS роль IAM применяет план терраформирования, потому что правило AWS s3 стандартного ACL для корзины: "private" ограничивает доступ к корзине, как: Владелец получает FULL_CONTROL. Больше ни у кого нет прав доступа (по умолчанию). в документации: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html

На этом этапе вы должны относительно четко указать, кто может получить доступ к корзине. Часто, если я использую частный ACL, но хочу, чтобы все остальные роли в моей учетной записи AWS имели доступ к корзине, я прикрепляю политику корзины к ресурсу terraform aws_s3_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
}
...