AWS Builder Center
Building Event-Driven Architectures on AWS with SQS, Lambda, and Terraform

Building Event-Driven Architectures on AWS with SQS, Lambda, and Terraform

Learn how to build a scalable and reliable event-driven architecture using Amazon SQS, AWS Lambda, and Terraform, with a practical flow from event producers to automated processing.

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
# Building Event-Driven Architectures on AWS with SQS, Lambda, and Terraform

Modern applications need to handle thousands of events without tightly coupling different components.

One effective approach is to use an **event-driven architecture**, where applications communicate through events instead of directly depending on each other.

In this article, we will build a simple event-driven architecture using:

- Amazon SQS
- AWS Lambda
- Terraform
- Amazon CloudWatch

The architecture will follow this flow:

**Producer → Amazon SQS → AWS Lambda → Processing**

---

## 1. What is Event-Driven Architecture?

In a traditional application, one service may directly call another service.

For example:

```text
Application → Backend → Database
If the backend is unavailable, the application may also be affected.
With an event-driven architecture, components can communicate asynchronously.
1
2
3
4
5
6
7
8
9
10
Producer
|
v
Amazon SQS
|
v
AWS Lambda
|
v
Processing
The producer sends a message to SQS and does not need to wait for Lambda to process it.
This creates a more loosely coupled and scalable system.

2. Why Use Amazon SQS?

Amazon Simple Queue Service (SQS) provides a reliable message queue between applications.
Instead of sending an event directly to a processing service, the producer places the event into a queue.
For example:
1
2
3
4
5
6
7
8
9
10
11
Order Service
|
| Order Created
v
SQS Queue
|
v
Lambda Function
|
v
Process Order
This provides several benefits:
  • Decoupling
  • Asynchronous processing
  • Automatic scaling
  • Message durability
  • Improved fault tolerance

3. Why Use AWS Lambda?

AWS Lambda allows us to run code without managing servers.
Lambda can consume messages from an SQS queue and process them automatically.
For example, when a new order is added to the queue:
1
2
3
4
5
6
7
8
9
10
SQS Message
|
v
Lambda Trigger
|
v
Process Order
|
v
Success
Lambda can process messages without requiring a continuously running EC2 instance.

4. Architecture

Our architecture will look like this:
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
+----------------+
| Producer |
| Application |
+-------+--------+
|
| Send Event
v
+----------------+
| Amazon SQS |
| Queue |
+-------+--------+
|
| Trigger
v
+----------------+
| AWS Lambda |
| Processor |
+-------+--------+
|
v
+----------------+
| Business |
| Processing |
+----------------+

|
v
+----------------+
| CloudWatch |
| Logs |
+----------------+
Terraform will be used to create and manage the infrastructure.

5. Creating the Infrastructure with Terraform

Instead of manually creating every AWS resource from the console, we can use Terraform.
Terraform allows us to define infrastructure as code.
Our project can have a simple structure:
1
2
3
4
5
6
7
event-driven-architecture/
│
ā”œā”€ā”€ main.tf
ā”œā”€ā”€ variables.tf
ā”œā”€ā”€ outputs.tf
└── lambda/
└── lambda_function.py

6. Create an SQS Queue

In main.tf:
1
2
3
4
5
resource "aws_sqs_queue" "event_queue" {
name = "event-processing-queue"

visibility_timeout_seconds = 60
}
This creates an SQS queue that will store incoming events.
The visibility timeout gives Lambda enough time to process a message before it becomes visible again.

7. Create the Lambda Function

We can define a Lambda function using Terraform:
1
2
3
4
5
6
7
8
9
10
11
resource "aws_lambda_function" "processor" {
function_name = "event-processor"

filename = "lambda.zip"
source_code_hash = filebase64sha256("lambda.zip")

handler = "lambda_function.lambda_handler"
runtime = "python3.12"

role = aws_iam_role.lambda_role.arn
}
Lambda will execute the Python function whenever messages are available for processing.

8. Connect SQS with Lambda

Now we need to connect our SQS queue to Lambda.
1
2
3
4
5
6
resource "aws_lambda_event_source_mapping" "sqs_lambda" {
event_source_arn = aws_sqs_queue.event_queue.arn
function_name = aws_lambda_function.processor.arn

batch_size = 10
}
This creates the event source mapping.
The flow becomes:
1
2
3
4
5
6
7
8
9
SQS
|
| Messages available
v
Lambda
|
| Process messages
v
Application Logic
Lambda polls the SQS queue and receives messages in batches.

9. Lambda Processing Code

A simple Python Lambda function can look like this:
1
import jsondef lambda_handler(event, context): for record in event["Records"]: message = record["body"] print("Received message:") print(message) return { "statusCode": 200, "body": json.dumps("Messages processed successfully") }
When Lambda receives messages from SQS, the messages are available inside:
1
event["Records"]
We can then process each message.

10. IAM Permissions

Lambda needs permission to interact with SQS.
A simplified IAM policy can provide the required SQS permissions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
resource "aws_iam_role_policy" "lambda_sqs_policy" {

role = aws_iam_role.lambda_role.id

policy = jsonencode({
Version = "2012-10-17"

Statement = [{
Effect = "Allow"

Action = [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
]

Resource = aws_sqs_queue.event_queue.arn
}]
})
}
IAM should always follow the principle of least privilege.
Only the permissions required by the Lambda function should be granted.

11. Deploying with Terraform

After configuring the resources, initialize Terraform:
1
terraform init
Review the infrastructure changes:
1
terraform plan
Apply the configuration:
1
terraform apply
Terraform will create the AWS infrastructure defined in the configuration.

12. Understanding the Complete Flow

Let's understand what happens when an event enters the system.

Step 1 — Producer creates an event

For example:
1
2
3
4
{
"order_id": "ORD-1001",
"event": "ORDER_CREATED"
}

Step 2 — Event is sent to SQS

The producer sends the event to the SQS queue.

Step 3 — SQS stores the message

SQS keeps the message until it is successfully processed.

Step 4 — Lambda receives the message

Lambda polls the queue through the event source mapping.

Step 5 — Lambda processes the event

The Lambda function executes the required business logic.

Step 6 — Message is removed

After successful processing, the message is deleted from the queue.
The complete flow is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Event
|
v
Producer
|
v
SQS Queue
|
v
Lambda
|
v
Processing
|
v
Success

13. What Happens When Processing Fails?

Failures are an important part of event-driven systems.
Suppose Lambda cannot process a message.
The message can become visible again after the visibility timeout.
This allows the system to retry processing.
A common architecture is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
+----------------+
| Main Queue |
+-------+--------+
|
v
Lambda
|
+------+------+
| |
Success Failure
| |
v v
Complete Retry
|
v
Dead Letter Queue
A Dead Letter Queue can be used to isolate messages that repeatedly fail.
This makes troubleshooting much easier.

14. Monitoring with CloudWatch

AWS Lambda automatically integrates with Amazon CloudWatch.
We can monitor:
  • Lambda invocations
  • Errors
  • Duration
  • Throttles
  • SQS message count
  • Failed processing attempts
CloudWatch logs can help us understand why a message failed.
For production systems, monitoring should be considered part of the architecture rather than an optional feature.

15. Benefits of This Architecture

This architecture provides several advantages.

Scalability

SQS can handle large numbers of messages while Lambda can scale based on incoming workload.

Loose Coupling

The producer does not need to directly communicate with the processing service.

Reliability

Messages remain in the queue until they are successfully processed.

Cost Efficiency

Lambda uses a serverless execution model, so there is no need to maintain an always-running server for the processing workload.

Infrastructure as Code

Terraform makes infrastructure repeatable and easier to manage across environments.

16. Best Practices

When building an SQS and Lambda architecture, consider the following:
  1. Use appropriate visibility timeout settings.
  2. Configure a Dead Letter Queue for important workloads.
  3. Follow the principle of least privilege with IAM.
  4. Monitor Lambda errors and SQS metrics.
  5. Choose an appropriate Lambda batch size.
  6. Make Lambda processing idempotent.
  7. Use CloudWatch for logging and monitoring.
  8. Keep infrastructure configuration in version control.
  9. Use Terraform modules for larger environments.
  10. Test failure and retry scenarios before production deployment.

17. Conclusion

Event-driven architecture helps applications become more scalable, loosely coupled, and resilient.
By combining:
Amazon SQS + AWS Lambda + Terraform
we can create an architecture where events are queued, processed asynchronously, and managed through Infrastructure as Code.
The key idea is simple:
1
2
3
4
5
6
7
8
9
Producer
↓
SQS
↓
Lambda
↓
Processing
↓
CloudWatch
Terraform then allows us to create and manage the infrastructure consistently.
This pattern can be extended to many real-world workloads such as order processing, notifications, background jobs, data processing, and asynchronous application workflows.
Build for failure, automate your infrastructure, and design your systems to scale.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

### šŸ·ļø Recommended Tags

Choose these **5 tags**:

- `AWS`
- `Amazon SQS`
- `AWS Lambda`
- `Terraform`
- `Serverless`

### šŸ–¼ļø Cover image

For the cover, I recommend a clean **1200 Ɨ 675** architecture graphic showing:

**Producer → SQS → Lambda → Processing → CloudWatch**

with **Terraform** represented underneath as the Infrastructure-as-Code layer.

If you want, I can also **create the AWS Builder cover image in the recommended 1200Ɨ675 format** for this article.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article