पाइथन और टेराफॉर्म का उपयोग करके एक डुअल-मोड AWS लैम्ब्डा बनाना
चरण-दर-चरण उदाहरण
इस पेज में हमने एक Python Lambda उदाहरण SQS संदेश प्रोसेसर + REST API के साथ API Key सुरक्षा + Terraform स्क्रिप्ट शामिल किया है, जो इसे सर्वरलेस एक्सीक्यूशन के लिए डिप्लॉय करने के लिए है।
AWS Lambda आपको हल्के सर्वरलेस फंक्शंस लिखने की अनुमति देता है जो लगभग किसी भी इवेंट के प्रति प्रतिक्रिया कर सकते हैं — SQS संदेशों से HTTP रिक्वेस्ट्स तक। इस गाइड में, हम एक एकल Python Lambda बनाएंगे जो दो मोड्स में काम करता है:
- SQS मोड: जब एक SQS संदेश जैसे
{ "par": 10 }
द्वारा ट्रिगर किया जाता है, यह{ "res": 11 }
को दूसरे क्यू में प्रकाशित करता है। - HTTP मोड: जब API Gateway द्वारा
GET /lam?par=10
के माध्यम से कॉल किया जाता है, यह{ "res": 11 }
को क्लाइंट को वापस करता है।
हम HTTP एंडपॉइंट को एक सरल हार्डकोडेड API key — "testkey"
का उपयोग करके सुरक्षित भी करेंगे। पूरे सेटअप को Terraform का उपयोग करके डिप्लॉय किया जाएगा।
आर्किटेक्चर ओवरव्यू
हम जो बना रहे हैं, उसे देखें:
एक ही Lambda दोनों के प्रति प्रतिक्रिया करता है:
- SQS इवेंट्स, एक इवेंट सोर्स मैपिंग के माध्यम से, और
- API Gateway रिक्वेस्ट्स, एक RESTful HTTP इंटीग्रेशन के माध्यम से।
चरण 1: Python में Lambda बनाना
एक बहुत ही सरल हैंडलर बनाएं Python जो एक SQS इवेंट और एक HTTP API कॉल के बीच अंतर कर सकता है।
फाइल: lambda_function.py
import json
import os
import boto3
sqs = boto3.client("sqs")
OUTPUT_QUEUE_URL = os.environ.get("OUTPUT_QUEUE_URL")
API_KEY = os.environ.get("API_KEY", "testkey") # हार्डकोडेड डिफ़ॉल्ट
def lambda_handler(event, context):
# इवेंट प्रकार का पता लगाएं
if "Records" in event: # SQS इवेंट
return handle_sqs(event["Records"])
else: # HTTP इवेंट
return handle_http(event)
def handle_sqs(records):
for record in records:
body = json.loads(record["body"])
par = int(body["par"])
res = par + 1
message = json.dumps({"res": res})
sqs.send_message(QueueUrl=OUTPUT_QUEUE_URL, MessageBody=message)
return {"status": "processed", "count": len(records)}
def handle_http(event):
headers = {k.lower(): v for k, v in (event.get("headers") or {}).items()}
if headers.get("x-api-key") != API_KEY:
return {
"statusCode": 403,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({"error": "Forbidden"})
}
params = event.get("queryStringParameters") or {}
if "par" not in params:
return {
"statusCode": 400,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({"error": "Missing par"})
}
par = int(params["par"])
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({"res": par + 1})
}
इस Lambda फंक्शन में हमने क्या रखा है:
- SQS संदेशों को JSON के रूप में पार्स किया जाता है।
- जब API Gateway द्वारा ट्रिगर किया जाता है, तो फंक्शन API key और क्वेरी पैरामीटर को वैलिडेट करता है।
- आउटपुट क्यू URL और API key को एन्वायरनमेंट वेरिएबल्स के माध्यम से पास किया जाता है।
चरण 2: Terraform के साथ डिप्लॉय करना
Terraform हमें AWS इन्फ्रास्ट्रक्चर — Lambda, SQS क्यूज़, API Gateway, और परमिशन्स — को एक साथ सेटअप करने की अनुमति देता है।
प्रोजेक्ट संरचना:
project/
├── lambda/
│ └── lambda_function.py
└── infra/
└── main.tf
Terraform कॉन्फ़िगरेशन (infra/main.tf
)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
archive = {
source = "hashicorp/archive"
}
}
}
provider "aws" {
region = "us-east-1"
}
locals {
project = "lambda-sqs-api"
}
# Lambda पैकेज
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "../lambda"
output_path = "lambda.zip"
}
# SQS क्यूज़
resource "aws_sqs_queue" "input" {
name = "${local.project}-input"
}
resource "aws_sqs_queue" "output" {
name = "${local.project}-output"
}
# Lambda के लिए IAM रोल
data "aws_iam_policy_document" "assume_role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role" "lambda_role" {
name = "${local.project}-role"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
resource "aws_iam_policy" "lambda_policy" {
name = "${local.project}-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"sqs:SendMessage",
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
]
Resource = "*"
},
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "*"
}
]
})
}
resource "aws_iam_role_policy_attachment" "lambda_policy_attach" {
role = aws_iam_role.lambda_role.name
policy_arn = aws_iam_policy.lambda_policy.arn
}
# Lambda फंक्शन
resource "aws_lambda_function" "func" {
filename = data.archive_file.lambda_zip.output_path
function_name = local.project
role = aws_iam_role.lambda_role.arn
handler = "lambda_function.lambda_handler"
runtime = "python3.12"
environment {
variables = {
OUTPUT_QUEUE_URL = aws_sqs_queue.output.id
API_KEY = "testkey"
}
}
}
# इवेंट सोर्स मैपिंग (SQS → Lambda)
resource "aws_lambda_event_source_mapping" "sqs_trigger" {
event_source_arn = aws_sqs_queue.input.arn
function_name = aws_lambda_function.func.arn
batch_size = 1
enabled = true
}
# API Gateway
resource "aws_api_gateway_rest_api" "api" {
name = "${local.project}-api"
}
resource "aws_api_gateway_resource" "lam" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_rest_api.api.root_resource_id
path_part = "lam"
}
resource "aws_api_gateway_method" "get_lam" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.lam.id
http_method = "GET"
authorization = "NONE"
api_key_required = true
}
resource "aws_api_gateway_integration" "lambda_integration" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.lam.id
http_method = aws_api_gateway_method.get_lam.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.func.invoke_arn
}
resource "aws_lambda_permission" "api_gateway" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.func.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_api_gateway_rest_api.api.execution_arn}/*/*"
}
# API Key और यूज़ेज़ प्लान
resource "aws_api_gateway_api_key" "key" {
name = "testkey"
value = "testkey"
enabled = true
}
resource "aws_api_gateway_usage_plan" "plan" {
name = "basic"
api_stages {
api_id = aws_api_gateway_rest_api.api.id
stage = aws_api_gateway_deployment.deploy.stage_name
}
}
resource "aws_api_gateway_usage_plan_key" "plan_key" {
key_id = aws_api_gateway_api_key.key.id
key_type = "API_KEY"
usage_plan_id = aws_api_gateway_usage_plan.plan.id
}
resource "aws_api_gateway_deployment" "deploy" {
depends_on = [aws_api_gateway_integration.lambda_integration]
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = "v1"
}
output "api_url" {
value = "${aws_api_gateway_deployment.deploy.invoke_url}/lam"
}
चरण 3: डिप्लॉय और टेस्ट करना
- Terraform को इनिशियलाइज़ करें:
cd infra
terraform init
- कॉन्फ़िगरेशन लागू करें:
terraform apply
- API Gateway एंडपॉइंट को टेस्ट करें:
curl -H "x-api-key: testkey" "<API_URL>?par=10"
# अपेक्षित प्राप्त करना: {"res": 11}
- SQS को टेस्ट करें:
इनपुट क्यू में एक संदेश भेजें:
aws sqs send-message --queue-url <input-queue-url> --message-body '{"par": 5}'
फिर आउटपुट क्यू को चेक करें:
aws sqs receive-message --queue-url <output-queue-url>
# अपेक्षित प्राप्त करना: {"res": 6}
चरण 4: क्लीन अप
सभी संसाधनों को हटाने के लिए:
terraform destroy
सारांश
[SQS इनपुट क्यू] ─▶ [Lambda फंक्शन] ─▶ [SQS आउटपुट क्यू]
▲
│
[API Gateway /lam?par=N]
│
API Key द्वारा सुरक्षित
आपने अभी एक मल्टी-ट्रिगर Lambda बनाया है जो:
- SQS क्यूज़ से कंस्यूम करता है और प्रकाशित करता है।
- API Gateway के माध्यम से HTTP रिक्वेस्ट्स का जवाब देता है।
- एक सरल हेडर चेक का उपयोग करके API key लागू करता है।
- Terraform के माध्यम से पूरी तरह से प्रबंधित किया जाता है, जो पुन: उत्पादन योग्य serverless इन्फ्रास्ट्रक्चर के लिए है।
यह पैटर्न हल्के संदेश ट्रांसफॉर्मर्स, हाइब्रिड माइक्रोसर्विसेज़, या असिंक्रोनस और सिंक्रोनस AWS सिस्टम्स को ब्रिज करने के लिए अच्छा है — सभी कुछ कुछ लाइन्स के Python और Terraform के साथ।
अगर आप AWS SAM का उपयोग करके एक थोड़ा अधिक उन्नत Lambda उदाहरण देखना चाहते हैं - तो कृपया इस पोस्ट को देखें: AWS SAM + AWS SQS + Python PowerTools का उपयोग करके Lambda कोडिंग