A complete Terraform configuration to deploy an SQS queue with a Lambda function trigger
This Terraform template creates an AWS SQS queue and configures a Lambda function to be triggered by messages in the queue. The template includes all necessary IAM permissions and resource configurations.
Standard queue with configurable visibility timeout and message retention
Node.js function with SQS trigger and proper IAM permissions
Least privilege permissions for Lambda to consume SQS messages
# Terraform configuration for AWS SQS with Lambda trigger
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
region = "us-east-1" # Change to your preferred region
}
# Create SQS queue
resource "aws_sqs_queue" "example_queue" {
name = "example-queue"
delay_seconds = 0
max_message_size = 262144 # 256 KiB
message_retention_seconds = 345600 # 4 days
receive_wait_time_seconds = 10 # Long polling wait time
visibility_timeout_seconds = 30 # Should be >= Lambda timeout
tags = {
Environment = "production"
}
}
# IAM role for Lambda execution
resource "aws_iam_role" "lambda_exec_role" {
name = "lambda_exec_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
}
# IAM policy for Lambda to access SQS
resource "aws_iam_policy" "lambda_sqs_policy" {
name = "lambda_sqs_policy"
description = "Policy for Lambda to read from SQS"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
]
Resource = aws_sqs_queue.example_queue.arn
},
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "arn:aws:logs:*:*:*"
}
]
})
}
# Attach policy to Lambda role
resource "aws_iam_role_policy_attachment" "lambda_sqs_attachment" {
role = aws_iam_role.lambda_exec_role.name
policy_arn = aws_iam_policy.lambda_sqs_policy.arn
}
# Lambda function
resource "aws_lambda_function" "sqs_processor" {
filename = "lambda_function.zip" # Replace with your Lambda package
function_name = "sqs_processor"
role = aws_iam_role.lambda_exec_role.arn
handler = "index.handler"
runtime = "nodejs14.x" # Change to your preferred runtime
source_code_hash = filebase64sha256("lambda_function.zip")
environment {
variables = {
QUEUE_URL = aws_sqs_queue.example_queue.url
}
}
}
# Lambda event source mapping
resource "aws_lambda_event_source_mapping" "sqs_trigger" {
event_source_arn = aws_sqs_queue.example_queue.arn
function_name = aws_lambda_function.sqs_processor.arn
batch_size = 10 # Number of messages to process at once
}
// Example Lambda function to process SQS messages
exports.handler = async (event) => {
console.log('Received event:', JSON.stringify(event, null, 2));
for (const record of event.Records) {
try {
const message = JSON.parse(record.body);
console.log('Processing message:', message);
// Your message processing logic here
// Example: Send to another service, transform data, etc.
console.log('Successfully processed message ID:', record.messageId);
} catch (error) {
console.error('Error processing message:', error);
// You might want to implement dead-letter queue handling here
throw error; // This will make Lambda retry the batch
}
}
return {
statusCode: 200,
body: JSON.stringify('Messages processed successfully')
};
};
main.tf
index.js
zip lambda_function.zip index.js
terraform init
terraform plan
terraform apply
terraform destroy