Deploy an AWS Lambda Function with Terraform
Deploying a Lambda with Terraform is one aws_lambda_function resource - but it fails to apply if you miss a required argument like runtime or get the handler wrong. Here's the working resource and the common errors.
The resource
An AWS Lambda in Terraform is the aws_lambda_function resource. The minimum that
actually applies:
resource "aws_lambda_function" "api" {
function_name = "my-api"
role = aws_iam_role.lambda.arn # an execution role
filename = "lambda.zip" # the packaged code
source_code_hash = filebase64sha256("lambda.zip")
handler = "lambda_function.lambda_handler" # file.function
runtime = "python3.12"
}
The arguments that trip people up
runtimeis required - omit it andterraform applyerrors before the function is created. Use a valid identifier likepython3.12,nodejs20.x,go1.x.handlerisfile.function- forlambda_function.pywith alambda_handlerfunction it'slambda_function.lambda_handler. A wrong handler deploys but fails at invoke time with "Unable to import module".source_code_hash- without it Terraform won't detect code changes, so re-deploys silently ship stale code.filebase64sha256()fixes that.role- Lambda needs an execution role ARN (even a minimal one with the basic logging policy).
Packaging the code
Terraform can zip the source for you so you don't commit a binary:
data "archive_file" "lambda" {
type = "zip"
source_file = "lambda_function.py"
output_path = "lambda.zip"
}
Then point filename and source_code_hash at data.archive_file.lambda.
Apply
terraform init
terraform apply -auto-approve
Read the error if it fails - Terraform names the missing/invalid argument directly (e.g. "argument runtime is required"). Fix that one line and re-apply.
Permissions, environment variables, and triggers
aws_lambda_function alone gives you a function that can run but can't do anything or be reached. Three things complete it:
- An execution role. The
roleargument points to an IAM role the function assumes. At minimum attachAWSLambdaBasicExecutionRoleso it can write CloudWatch logs; add more for whatever services it calls (S3, DynamoDB). - Environment variables. Pass config with an
environment { variables = { ... } }block instead of hard-coding - the function reads them fromos.environ. - A trigger. A function with no invoker never runs. Wire one with
aws_lambda_permissionplus the source: an API Gateway route, an S3 notification, an SQS event source mapping, or an EventBridge schedule.
Common apply errors are a missing role, a handler that doesn't match file.function in your code, or a runtime AWS does not recognize. Fix them one at a time and re-run terraform apply.
Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.
Try it in a workspace →What you'll practice
- Writing a working aws_lambda_function resource
- Packaging code with archive_file + source_code_hash
- Reading terraform apply errors to fix the missing argument
FAQ
Why does terraform apply fail on aws_lambda_function?
Usually a missing required argument - most often runtime - or an invalid value. Terraform names it in the error; add the argument (e.g. runtime = "python3.12") and re-apply.
What is the Lambda handler in Terraform?
handler is filename.function_name of your code's entry point - e.g. lambda_function.lambda_handler for a lambda_handler function in lambda_function.py. A wrong handler deploys but errors at invoke with 'Unable to import module'.
How do I make Terraform redeploy changed Lambda code?
Set source_code_hash = filebase64sha256("lambda.zip") (or use an archive_file data source). Without it Terraform doesn't notice code changes and ships the old zip.
Keep learning
Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.
Open the workspace →