AutoDeploy

Terraform Demos

Copy and modify these pre-built Terraform configurations for your infrastructure.

AWS

AWS Lambda Function with API Gateway

AWSUploaded

Create a Lambda function with an HTTP API Gateway integration.

By System · Other

main.tf · variables.tf · outputs.tf

Download
resource "aws_iam_role" "lambda" {
  name = "${var.function_name}-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "lambda.amazonaws.com" }
      Action    = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_role_policy_attachment" "lambda_basic" {
  role       = aws_iam_role.lambda.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

resource "aws_lambda_function" "app" {
  function_name = var.function_name
  role          = aws_iam_role.lambda.arn
  handler       = var.handler
  runtime       = var.runtime
  filename      = var.zip_path
  timeout       = 10
}

resource "aws_apigatewayv2_api" "http" {
  name          = "${var.function_name}-api"
  protocol_type = "HTTP"
}

resource "aws_apigatewayv2_integration" "lambda" {
  api_id                 = aws_apigatewayv2_api.http.id
  integration_type       = "AWS_PROXY"
  integration_uri        = aws_lambda_function.app.invoke_arn
  payload_format_version = "2.0"
}

resource "aws_apigatewayv2_route" "default" {
  api_id    = aws_apigatewayv2_api.http.id
  route_key = "$default"
  target    = "integrations/${aws_apigatewayv2_integration.lambda.id}"
}

resource "aws_apigatewayv2_stage" "default" {
  api_id      = aws_apigatewayv2_api.http.id
  name        = "$default"
  auto_deploy = true
}

resource "aws_lambda_permission" "apigw" {
  statement_id  = "AllowAPIGatewayInvoke"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.app.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn    = "${aws_apigatewayv2_api.http.execution_arn}/*/*"
}

variable "function_name" {
  type = string
}

variable "handler" {
  type    = string
  default = "index.handler"
}

variable "runtime" {
  type    = string
  default = "nodejs20.x"
}

variable "zip_path" {
  type = string
}

Troubleshooting & Solutions

Common Issues

  • 403 Forbidden calling the API
  • Lambda times out on cold start
  • Deployment package too large

Solutions

  • Confirm the aws_lambda_permission resource exists and its source_arn matches the actual API
  • Increase the timeout and memory for functions with heavy cold-start init work
  • Use Lambda layers or container images for large dependencies instead of one big zip

Troubleshooting Steps

  1. Check CloudWatch Logs for the specific Lambda invocation error
  2. Verify the IAM role has the AWSLambdaBasicExecutionRole policy attached
  3. Confirm payload_format_version matches what your handler code expects (1.0 vs 2.0 event shape differs)
  4. Test the function directly with `aws lambda invoke` before blaming API Gateway

Version compatibility: Terraform >= 1.0, AWS Provider >= 5.0