Deploy a serverless REST API on AWS that allows users to perform CRUD (Create, Read, Update, Delete) operations on a DynamoDB table. The API is managed via API Gateway, and the business logic is handled using AWS Lambda functions written in Python. Terraform is used to provision all the infrastructure.
aws configure
Terraform will be used to define:
provider.tf
)provider "aws" {
region = "us-east-1"
}
iam.tf
)resource "aws_iam_role" "lambda_role" {
name = "serverless_lambda_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_dynamodb" {
name = "lambda-dynamodb-policy"
roles = [aws_iam_role.lambda_role.name]
policy_arn = "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"
}
dynamodb.tf
)resource "aws_dynamodb_table" "users" {
name = "users"
billing_mode = "PAY_PER_REQUEST"
hash_key = "userId"
attribute {
name = "userId"
type = "S"
}
}
lambda.tf
)resource "aws_lambda_function" "crud_lambda" {
filename = "lambda_function.zip"
function_name = "crudLambda"
role = aws_iam_role.lambda_role.arn
handler = "lambda_function.lambda_handler"
runtime = "python3.9"
environment {
variables = {
TABLE_NAME = aws_dynamodb_table.users.name
}
}
}
lambda_function.py
)This function performs CRUD operations based on API Gateway requests.
import json
import boto3
import os
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(os.environ["TABLE_NAME"])
def lambda_handler(event, context):
http_method = event["httpMethod"]
body = json.loads(event.get("body", "{}"))
if http_method == "POST":
table.put_item(Item=body)
return {"statusCode": 200, "body": json.dumps("User created")}
elif http_method == "GET":
user_id = event["queryStringParameters"]["userId"]
response = table.get_item(Key={"userId": user_id})
return {"statusCode": 200, "body": json.dumps(response.get("Item", {}))}
elif http_method == "PUT":
user_id = body["userId"]
table.update_item(
Key={"userId": user_id},
UpdateExpression="SET age = :age",
ExpressionAttributeValues={":age": body["age"]}
)
return {"statusCode": 200, "body": json.dumps("User updated")}
elif http_method == "DELETE":
user_id = event["queryStringParameters"]["userId"]
table.delete_item(Key={"userId": user_id})
return {"statusCode": 200, "body": json.dumps("User deleted")}
return {"statusCode": 400, "body": json.dumps("Invalid request")}
resource "aws_api_gateway_rest_api" "serverless_api" {
name = "ServerlessAPI"
description = "API Gateway for Serverless App"
}
resource "aws_api_gateway_resource" "users_resource" {
rest_api_id = aws_api_gateway_rest_api.serverless_api.id
parent_id = aws_api_gateway_rest_api.serverless_api.root_resource_id
path_part = "users"
}
resource "aws_api_gateway_method" "users_method" {
rest_api_id = aws_api_gateway_rest_api.serverless_api.id
resource_id = aws_api_gateway_resource.users_resource.id
http_method = "POST"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "lambda_integration" {
rest_api_id = aws_api_gateway_rest_api.serverless_api.id
resource_id = aws_api_gateway_resource.users_resource.id
http_method = aws_api_gateway_method.users_method.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.crud_lambda.invoke_arn
}
Run the following commands to deploy:
terraform init
terraform apply -auto-approve
Once deployed, get the API Gateway URL from Terraform output and test it using cURL or Postman
curl -X POST https://your-api-id.execute-api.us-east-1.amazonaws.com/users \
-H "Content-Type: application/json" \
-d '{"userId": "123", "name": "John Doe", "age": 30}'
curl -X GET "https://your-api-id.execute-api.us-east-1.amazonaws.com/users?userId=123"
curl -X PUT https://your-api-id.execute-api.us-east-1.amazonaws.com/users \
-H "Content-Type: application/json" \
-d '{"userId": "123", "age": 31}'
curl -X DELETE "https://your-api-id.execute-api.us-east-1.amazonaws.com/users?userId=123"
To delete all AWS resources, run:
terraform destroy -auto-approve
This project deploys a serverless API with AWS Lambda, API Gateway, and DynamoDB using Terraform. The architecture is scalable, cost-efficient, and fully managed by AWS.