Terraform模块为lambda函数创建S3存储桶,可以访问交叉帐户吗?

时间:2018-02-22 10:57:58

标签: amazon-s3 terraform

我是Terraform的新手,我正在尝试为Lambda函数创建一个Terraform模块S3存储桶,可以通过交叉帐户访问。此外,Cross帐户访问权限应限于列出和获取对象。

以下是我创建lambda的内容:

resource "aws_lambda_function" "test_lambda" {
  filename         = "lambda_function_payload.zip"
  s3_bucket        = "my_bucket_name"
  function_name    = "lambda_function_name"
  role             = "${aws_iam_role.iam_for_lambda.arn}"
  handler          = "exports.test"
  source_code_hash = "${base64sha256(file("lambda_function_payload.zip"))}"
  runtime          = "nodejs4.3"
}

这就是我的s3存储桶代码的样子:

resource "aws_s3_bucket" "bucket" {
  bucket = "my-bucket"
  acl    = "private"

  lifecycle_rule {
    id      = "log"
    enabled = true

    prefix = "log/"

    tags {
      "rule"      = "log"
      "autoclean" = "true"
    }

    transition {
      days          = 30
      storage_class = "STANDARD_IA"
    }

    transition {
      days          = 60
      storage_class = "GLACIER"
    }

    expiration {
      days = 90
    }
  }

  lifecycle_rule {
    id      = "tmp"
    prefix  = "tmp/"
    enabled = true

    expiration {
      date = "2016-01-12"
    }
  }

  #Using this section for cors_rule
  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["GET"]
    allowed_origins = ["https://s3-website-test.hashicorp.com"]
  }
}

如何将其转变为模块?

1 个答案:

答案 0 :(得分:0)

official documentation中描述了必要的政策。在下文中,我将介绍如何使用单个terraform模块设置此示例 - 您必须根据需要调整权限。您还可以对其进行扩展,以支持2个以上的AWS账户。我自己没有运行以下代码,所以可能会有一些拼写错误等,但它应该可以帮助你了解它背后的一般想法。

假设AWS账户A是您的s3存储桶所在的账户,而AWS账户B是您运行lambda功能的账户。

为了将所有内容放入单个模块,您必须定义2个Terraform AWS提供程序;每个涉及的AWS账户一个。

// Your s3 bucket's provider - used by default
provider "aws" {
  .. // your setup here
}

// Your lambda function's provider - used if specified via alias
provider "aws" {
  .. // your setup here

  alias = "lambda"
}

首先,将策略附加到您的s3存储桶以允许来自帐户B的访问:

data "aws_caller_identity" "lambda" {
  provider = "aws.lambda"
}

data "aws_iam_policy_document" "s3_cross_account" {
  policy_id = "Cross account access for s3"

  statement {
    sid= "1"

    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::${data.aws_caller_identity.lambda.account_id}:root"]
    }

    actions    = [""s3:GetBucketLocation", "s3:ListBucket"]
    resources  = ["arn:aws:s3:::${aws_s3_bucket.bucket.bucket}"]
  }
}

resource "aws_s3_bucket_policy" "s3_cross_account" {
  bucket = "${aws_s3_bucket.bucket.id}"
  policy = "${data.aws_iam_policy_document.s3_cross_account.json}"
}

接下来,在AWS账户B中创建一个可由lambda函数使用的角色:

data "aws_iam_policy_document" "access_cross_account_s3" {
  provider = "aws.lambda"

  policy_id = "Cross account access for s3"

  statement {
    sid= "1"

    actions    = ["s3:ListBucket"]
    resources  = ["arn:aws:s3:::${aws_s3_bucket.bucket.bucket}"]
  }
}

resource "aws_iam_role" "s3_cross_account" {
  provider = "aws.lambda"

  name = "s3_cross_account"
  assume_role_policy = "${data.aws_iam_policy_document.access_cross_account_s3.json}"
}

您的lambda函数代码块还必须具有provider = "aws.lambda"配置集,因此它在AWS账户B中创建。