Why do I get "Error: handler and runtime must be set when PackageType is Zip" when deploying a Lambda function using Terraform?

Question:

I have defined a Lambda function with Terraform like this:

resource "aws_lambda_function" "this" {
  filename = "${path.module}/src/existing-files-lambda.zip"
  function_name = "ingest-existing-files-lambda"
  role = aws_iam_role.lambda.arn

  runtime = "python3.9"
  timeout = 900
  environment {
   variables = {
      source_bucket_arn = var.source_bucket_arn  
      destination_bucket_arn = var.destination_bucket_arn  
    }
  }
}

resource "aws_iam_role" "lambda" {
  name = "${var.prefix}-lambda-ingest"
  path = "/service-role/"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "lambda.amazonaws.com" }
      Action    = "sts:AssumeRole"
    }]
  })
}

My python file is just this:

import os


def lambda_handler(event, context):
    print('Hello world from Terraform')
    return {
        'statusCode': 200,
    }

However, I am currently getting an error that:

│ Error: handler and runtime must be set when PackageType is Zip
│ 
│   with module.ingest_lambda.aws_lambda_function.this,
│   on ingest_lambda/main.tf line 8, in resource "aws_lambda_function" "this":
│    8: resource "aws_lambda_function" "this" {

What do I put as handler here?

I already have runtime specified.

Asked By: user13067694

||

Answers:

I think that you need to add a handler here:

resource "aws_lambda_function" "this" {
  filename = "${path.module}/src/existing-files-lambda.zip"
  function_name = "ingest-existing-files-lambda"
  handler = "ingest-existing-files-lambda.lambda_handler"
  role = aws_iam_role.lambda.arn

  runtime = "python3.9"
  timeout = 900
  environment {
   variables = {
      source_bucket_arn = var.source_bucket_arn  
      destination_bucket_arn = var.destination_bucket_arn  
    }
  }
}

Check in your AWS console, in the lambda service that the handler is correctly set once the statement above executed.

Answered By: David Brabant

You have defined the Lambda function runtime but you haven’t mentioned where the entry point to the function is.


That is what the handler argument specifies – it is the method in your function code that processes events.

It should have a format similar to:

def handler_name(event, context): 
    ...
    return some_value

The value of the handler argument is comprised of the below, separated by a dot:

  • The name of the file in which the Lambda handler function is located
  • The name of the Python handler function.

e.g.
ingest-existing-files-lambda.lambda_handler calls thelambda_handler function defined in ingest-existing-files-lambda.py.

If your Lambda handler method is called lambda_handler & is inside ingest-existing-files-lambda.py, this should work:

resource "aws_lambda_function" "this" {
  filename = "${path.module}/src/existing-files-lambda.zip"
  function_name = "ingest-existing-files-lambda"
  handler = "ingest-existing-files-lambda.lambda_handler"
  role = aws_iam_role.lambda.arn

  runtime = "python3.9"
  timeout = 900
  environment {
   variables = {
      source_bucket_arn = var.source_bucket_arn  
      destination_bucket_arn = var.destination_bucket_arn  
    }
  }
}
Answered By: Ermiya Eskandary

I faced the same issue. After defining the function runtime it worked for me.

Answered By: Mr. Nobody