Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to grant lambda permission to upload file to s3 bucket in `terraform`?

I have below lambda function configuration in TerraForm:

resource "aws_lambda_function" "test_lambda" {
  # filename         = "crawler/dist/deploy.zip"
  s3_bucket = "${var.s3-bucket}"
  s3_key    = "${aws_s3_bucket_object.file_upload.key}"
  # source_code_hash = "${filebase64sha256("file.zip")}"
  function_name    = "quote-crawler"
  role             = "arn:aws:iam::773592622512:role/LambdaRole"
  handler          = "handler.handler"
  source_code_hash = "${data.archive_file.zipit.output_base64sha256}"
  runtime          = "${var.runtime}"
  timeout          = 180

  environment {
    variables = {
      foo = "bar"
    }
  }
}

when I run the lambda I got the error "errorMessage": "An error occurred (AccessDenied) when calling the PutObject operation: Access Denied", when it tries to upload file to s3 bucket. It seems that the lambda function doesn't have permission to access s3. TerraForm doc is not clear about how to configure them. The permission configuration panel doesn't appear on lambda console either. It seems that lambda that created by TerraForm has limited configuration for me to use. So how can I grant s3 permission to lambda?

like image 340
Joey Yi Zhao Avatar asked Jul 22 '19 11:07

Joey Yi Zhao


People also ask

Can Lambda upload file to S3?

Introduction to Cloud Computing on AWS for Beginners [2022] Amazon S3 service is used for file storage, where you can upload or remove files. We can trigger AWS Lambda on S3 when there are any file uploads in S3 buckets. AWS Lambda has a handler function which acts as a start point for AWS Lambda function.

How do you add permission to Lambda function?

Open the Functions page of the Lambda console. Choose a function. Choose Configuration and then choose Permissions. Scroll down to Resource-based policy and then choose View policy document.


1 Answers

To make it easy you can do this in three steps,

  1. create a role
  2. create policy
  3. attached policy to the role
  4. attached role to lambda

Create role.

resource "aws_iam_role" "role" {
  name = "${var.env_prefix_name}-alb-logs-to-elk"
  path = "/"

      assume_role_policy = <<EOF
    {

  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

Create a policy that has specified access to s3

 #Created Policy for IAM Role
resource "aws_iam_policy" "policy" {
  name = "${var.env_prefix_name}-test-policy"
  description = "A test policy"


      policy = <<EOF
   {
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "logs:*"
        ],
        "Resource": "arn:aws:logs:*:*:*"
    },
    {
        "Effect": "Allow",
        "Action": [
            "s3:*"
        ],
        "Resource": "arn:aws:s3:::*"
    }
]

} 
    EOF
    }

Attached IAM Role and the new created Policy

resource "aws_iam_role_policy_attachment" "test-attach" {
  role       = "${aws_iam_role.role.name}"
  policy_arn = "${aws_iam_policy.policy.arn}"
}

Now attached the role to Lamba source

resource "aws_lambda_function" "test_lambda" {
  # filename         = "crawler/dist/deploy.zip"
  s3_bucket = "${var.s3-bucket}"
  s3_key    = "${aws_s3_bucket_object.file_upload.key}"
  # source_code_hash = "${filebase64sha256("file.zip")}"
  function_name    = "quote-crawler"
  role             = "${aws_iam_role.role.arn}"
  handler          = "handler.handler"
  source_code_hash = "${data.archive_file.zipit.output_base64sha256}"
  runtime          = "${var.runtime}"
  timeout          = 180

  environment {
    variables = {
      foo = "bar"
    }
  }
}
like image 115
Adiii Avatar answered Sep 30 '22 19:09

Adiii