Deploy AWS Lambda Function with API Gateway Using Terraform

In this article we are going to cover How to Deploy an AWS Lambda Function with API Gateway Using Terraform

In modern cloud applications, serverless computing offers scalability, cost-efficiency, and ease of management. AWS Lambda allows you to run code without provisioning or managing servers, while API Gateway enables you to create secure and scalable RESTful APIs.

This guide provides a step-by-step process to deploy an AWS Lambda function with API Gateway using Terraform. You will learn how to define the necessary IAM roles, create the Lambda function, configure API Gateway, and deploy everything using Terraform. By the end of this guide, you will have a working API that triggers your Lambda function upon receiving HTTP requests.

Prerequisites

  • An AWS account with necessary IAM permissions
  • Terraform installed on your local machine
  • AWS CLI configured with appropriate credentials
  • Ubuntu 24.04 with zip installed (for packaging the Python Lambda function)

Directory Structure

Below is the recommended directory structure for this project:

terra/
├── api_gateway.tf
├── iam.tf
├── lambda.tf
├── lambda_function
│   ├── lambda_function.py
│   ├── lambda_function.zip
│   └── zip_lambda.sh
├── provider.tf

Step #1:Set Up Terraform Provider for AWS

Create a provider.tf file to define the AWS provider:

provider "aws" {
  region = "ap-south-1"  # Change to your preferred region
}

Step #2:Create an IAM Role in AWS for Lambda

Define an IAM role for the Lambda function in iam.tf:

resource "aws_iam_role" "lambda_role" {
  name = "lambda_execution_role"

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

resource "aws_iam_policy_attachment" "lambda_policy" {
  name       = "lambda_basic_execution"
  roles      = [aws_iam_role.lambda_role.name]
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

Step #3:Create the Lambda Function

Define the Lambda function in lambda.tf:

resource "aws_lambda_function" "my_lambda" {
  filename      = "${path.module}/lambda_function/lambda_function.zip"
  function_name = "MyLambdaFunction"
  role          = aws_iam_role.lambda_role.arn
  handler       = "lambda_function.lambda_handler"
  runtime       = "python3.9"
}

Step #4:Create API Gateway in AWS using Terraform

Define API Gateway in api_gateway.tf:

resource "aws_api_gateway_rest_api" "lambda_api" {
  name        = "LambdaAPI"
  description = "API Gateway for Lambda Function"
}

resource "aws_api_gateway_resource" "proxy" {
  rest_api_id = aws_api_gateway_rest_api.lambda_api.id
  parent_id   = aws_api_gateway_rest_api.lambda_api.root_resource_id
  path_part   = "{proxy+}"
}

resource "aws_api_gateway_method" "proxy_method" {
  rest_api_id   = aws_api_gateway_rest_api.lambda_api.id
  resource_id   = aws_api_gateway_resource.proxy.id
  http_method   = "ANY"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda_integration" {
  rest_api_id = aws_api_gateway_rest_api.lambda_api.id
  resource_id = aws_api_gateway_resource.proxy.id
  http_method = aws_api_gateway_method.proxy_method.http_method

  integration_http_method = "POST"
  type                   = "AWS_PROXY"
  uri                    = aws_lambda_function.my_lambda.invoke_arn
}

resource "aws_api_gateway_stage" "dev" {
  rest_api_id   = aws_api_gateway_rest_api.lambda_api.id
  deployment_id = aws_api_gateway_deployment.lambda_api_deployment.id
  stage_name    = "dev"
}

resource "aws_api_gateway_deployment" "lambda_api_deployment" {
  depends_on  = [aws_api_gateway_integration.lambda_integration]
  rest_api_id = aws_api_gateway_rest_api.lambda_api.id
}

resource "aws_lambda_permission" "apigw" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.my_lambda.function_name
  principal     = "apigateway.amazonaws.com"
  source_arn    = "${aws_api_gateway_rest_api.lambda_api.execution_arn}/*/*"
}

Step #5:Create Lambda Function Code

Inside the lambda_function/ directory, create lambda_function.py:

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': 'Hello from Lambda!'
    }

Create a zip_lambda.sh script to package the Lambda function:

#!/bin/bash
zip lambda_function.zip lambda_function.py

Make it executable and run it:

chmod +x zip_lambda.sh
./zip_lambda.sh

A lambda_function.zip file will be created after running above commands:

Deploy AWS Lambda Function with API Gateway Using Terraform 1

Step #6:Deploy AWS Lambda Function with API Gateway Using Terraform

Run the following Terraform commands:

terraform init
Deploy AWS Lambda Function with API Gateway Using Terraform 2
terraform plan
Deploy AWS Lambda Function with API Gateway Using Terraform 3
terraform apply -auto-approve
Deploy AWS Lambda Function with API Gateway Using Terraform 4

Check the Lambda Function:

Deploy AWS Lambda Function with API Gateway Using Terraform 5

Check the API Gateway endpoint url for the deployment:

Deploy AWS Lambda Function with API Gateway Using Terraform 6
Deploy AWS Lambda Function with API Gateway Using Terraform 7

Step #7:Destroy Resources

To remove all resources created by Terraform, run:

terraform destroy -auto-approve
Deploy AWS Lambda Function with API Gateway Using Terraform 8

Conclusion:

You have successfully deployed an AWS Lambda function with API Gateway using Terraform. Now, your Lambda function is accessible via an HTTP request, enabling seamless serverless application deployment.

Related Articles:

How to Create Amazon EKS Cluster Using Terraform

Reference:

Serverless Applications with AWS Lambda and API Gateway Terraform official page

Harish Reddy

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link
Powered by Social Snap