Voiced by Amazon Polly |
Serverless architectures have transformed cloud computing by eliminating infrastructure management while ensuring high scalability and cost efficiency. In this guide, we will deploy a serverless application using Terraform, leveraging AWS Lambda, API Gateway, and S3 to build a fully automated and scalable solution.
Transform Your Career with AWS Certifications
- Advanced Skills
- AWS Official Curriculum
- 10+ Hand-on Labs
Why Serverless?
- No infrastructure management
- Auto-scaling based on demand
- Pay-per-use pricing model
- Faster development and deployment
Steps to Deploy the Serverless Application
We will:
- Set up infrastructure with Terraform.
- Package and deploy a Lambda function.
- Integrate it with API Gateway.
- Test the entire workflow.
Task 1: Create Infrastructure
1. Create a Directory and Configure Terraform
1 |
mkdir serverless && cd serverless |
2. Define AWS Provider and S3 Bucket
Create main.tf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
provider "aws" { region = var.aws_region } resource "random_pet" "lambda_bucket_name" { prefix = "learn-terraform-functions" length = 4 } resource "aws_s3_bucket" "lambda_bucket" { bucket = random_pet.lambda_bucket_name.id } resource "aws_s3_bucket_ownership_controls" "lambda_bucket" { bucket = aws_s3_bucket.lambda_bucket.id rule { object_ownership = "BucketOwnerPreferred" } } resource "aws_s3_bucket_acl" "lambda_bucket" { depends_on = [aws_s3_bucket_ownership_controls.lambda_bucket] bucket = aws_s3_bucket.lambda_bucket.id acl = "private" } |
3. Define Outputs
Create output.tf:
1 2 3 4 |
output "lambda_bucket_name" { description = "Name of the S3 bucket used to store function code." value = aws_s3_bucket.lambda_bucket.id } |
4. Define Variables
Create variables.tf:
1 2 3 4 5 |
variable "aws_region" { description = "AWS region for all resources." type = string default = "us-east-1" } |
5. Initialize and Apply Terraform
1 2 |
terraform init terraform apply --auto-approve |
Task 2: Create and Upload Lambda Function Archive
1. Create a Node.js Lambda Function
1 |
mkdir hello-world && cd hello-world |
Create hello.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
module.exports.handler = async (event) => { console.log('Event: ', event); let responseMessage = 'Hello, World!'; return { statusCode: 200, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message: responseMessage, }), } } |
2. Package and Upload the Function
Create s3_object.tf:
1 2 3 4 5 6 7 8 9 10 11 12 |
data "archive_file" "lambda_hello_world" { type = "zip" source_dir = "${path.module}/hello-world" output_path = "${path.module}/hello-world.zip" } resource "aws_s3_object" "lambda_hello_world" { bucket = aws_s3_bucket.lambda_bucket.id key = "hello-world.zip" source = data.archive_file.lambda_hello_world.output_path etag = filemd5(data.archive_file.lambda_hello_world.output_path) } |
3. Apply Configuration
1 2 |
terraform init -upgrade terraform apply --auto-approve |
Task 3: Create the Lambda Function
1. Define Lambda Function and IAM Role
Create lambda.tf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
resource "aws_lambda_function" "hello_world" { function_name = "MeharHelloWorld" s3_bucket = aws_s3_bucket.lambda_bucket.id s3_key = aws_s3_object.lambda_hello_world.key runtime = "nodejs20.x" handler = "hello.handler" source_code_hash = data.archive_file.lambda_hello_world.output_base64sha256 role = aws_iam_role.lambda_exec.arn } resource "aws_cloudwatch_log_group" "hello_world" { name = "/aws/lambda/${aws_lambda_function.hello_world.function_name}" retention_in_days = 30 } resource "aws_iam_role" "lambda_exec" { name = "mehar-serverless_lambda" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [{ Action = "sts:AssumeRole" Effect = "Allow" Sid = "" Principal = { Service = "lambda.amazonaws.com" } }] }) } resource "aws_iam_role_policy_attachment" "lambda_policy" { role = aws_iam_role.lambda_exec.name policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" } |
2. Add Lambda Output
Create outputs_lambda.tf:
1 2 3 4 |
output "function_name" { description = "Name of the Lambda function." value = aws_lambda_function.hello_world.function_name } |
3. Apply and Test Lambda
1 2 3 |
terraform apply --auto-approve aws lambda invoke --region=us-east-1 --function-name=$(terraform output -raw function_name) response.json cat response.json |
Task 4: Create an HTTP API with API Gateway
1. Define API Gateway Resources
Create api.tf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
resource "aws_apigatewayv2_api" "lambda" { name = "mehar-serverless_lambda_gw" protocol_type = "HTTP" } resource "aws_apigatewayv2_stage" "lambda" { api_id = aws_apigatewayv2_api.lambda.id name = "mehar-serverless_lambda_stage" auto_deploy = true access_log_settings { destination_arn = aws_cloudwatch_log_group.api_gw.arn format = jsonencode({ requestId = "$context.requestId" sourceIp = "$context.identity.sourceIp" requestTime = "$context.requestTime" protocol = "$context.protocol" httpMethod = "$context.httpMethod" resourcePath = "$context.resourcePath" routeKey = "$context.routeKey" status = "$context.status" responseLength = "$context.responseLength" integrationErrorMessage = "$context.integrationErrorMessage" }) } } resource "aws_apigatewayv2_integration" "hello_world" { api_id = aws_apigatewayv2_api.lambda.id integration_uri = aws_lambda_function.hello_world.invoke_arn integration_type = "AWS_PROXY" integration_method = "POST" } resource "aws_apigatewayv2_route" "hello_world" { api_id = aws_apigatewayv2_api.lambda.id route_key = "GET /hello" target = "integrations/${aws_apigatewayv2_integration.hello_world.id}" } resource "aws_cloudwatch_log_group" "api_gw" { name = "/aws/api_gw/${aws_apigatewayv2_api.lambda.name}" retention_in_days = 30 } resource "aws_lambda_permission" "api_gw" { statement_id = "AllowExecutionFromAPIGateway" action = "lambda:InvokeFunction" function_name = aws_lambda_function.hello_world.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_apigatewayv2_api.lambda.execution_arn}/*/*" } |
2. Add API Output
Create outputs_api.tf:
output “base_url” {
description = “Base URL for API Gateway stage.”
value = aws_apigatewayv2_stage.lambda.invoke_url
}
3. Apply and Test API Gateway
1 2 |
terraform apply --auto-approve curl "$(terraform output -raw base_url)/hello" |
Task 5: Clean Up Resources
1 2 |
terraform destroy --auto-approve cd ~ && rm -rf serverless |
Conclusion
By following this guide, you have successfully deployed a serverless application using Terraform, integrating AWS Lambda, API Gateway, and S3. This setup ensures scalability, cost efficiency, and ease of management while eliminating the need for manual infrastructure handling.
Earn Multiple AWS Certifications for the Price of Two
- AWS Authorized Instructor led Sessions
- AWS Official Curriculum
About CloudThat
CloudThat is a leading provider of Cloud Training and Consulting services with a global presence in India, the USA, Asia, Europe, and Africa. Specializing in AWS, Microsoft Azure, GCP, VMware, Databricks, and more, the company serves mid-market and enterprise clients, offering comprehensive expertise in Cloud Migration, Data Platforms, DevOps, IoT, AI/ML, and more.
CloudThat is the first Indian Company to win the prestigious Microsoft Partner 2024 Award and is recognized as a top-tier partner with AWS and Microsoft, including the prestigious ‘Think Big’ partner award from AWS and the Microsoft Superstars FY 2023 award in Asia & India. Having trained 650k+ professionals in 500+ cloud certifications and completed 300+ consulting projects globally, CloudThat is an official AWS Advanced Consulting Partner, Microsoft Gold Partner, AWS Training Partner, AWS Migration Partner, AWS Data and Analytics Partner, AWS DevOps Competency Partner, AWS GenAI Competency Partner, Amazon QuickSight Service Delivery Partner, Amazon EKS Service Delivery Partner, AWS Microsoft Workload Partners, Amazon EC2 Service Delivery Partner, Amazon ECS Service Delivery Partner, AWS Glue Service Delivery Partner, Amazon Redshift Service Delivery Partner, AWS Control Tower Service Delivery Partner, AWS WAF Service Delivery Partner, Amazon CloudFront, Amazon OpenSearch, AWS DMS, AWS Systems Manager, Amazon RDS, and many more.

WRITTEN BY Mehar Nafis
Comments