Skip to content

Commit 463c6aa

Browse files
committed
Add compute tutorials (batch 2)
1 parent 49f07d9 commit 463c6aa

11 files changed

Lines changed: 1018 additions & 0 deletions

File tree

tuts/084-lambda-sqs/README.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Lambda: Process SQS messages
2+
3+
Create a Lambda function that processes messages from an Amazon SQS queue, with event source mapping for automatic invocation.
4+
5+
## Source
6+
7+
https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-example.html
8+
9+
## Use case
10+
11+
- ID: lambda/sqs-trigger
12+
- Phase: create
13+
- Complexity: beginner
14+
- Core actions: lambda:CreateFunction, lambda:CreateEventSourceMapping, sqs:SendMessage
15+
16+
## What it does
17+
18+
1. Creates an IAM execution role with SQS permissions
19+
2. Creates a Node.js Lambda function that logs message bodies
20+
3. Tests the function with a sample SQS event
21+
4. Creates an SQS queue
22+
5. Creates an event source mapping (queue → function)
23+
6. Sends test messages to the queue
24+
7. Verifies processing via CloudWatch Logs
25+
8. Cleans up all resources
26+
27+
## Running
28+
29+
```bash
30+
bash lambda-sqs.sh
31+
```
32+
33+
To auto-run with cleanup:
34+
35+
```bash
36+
echo 'y' | bash lambda-sqs.sh
37+
```
38+
39+
## Resources created
40+
41+
- IAM role (with AWSLambdaSQSQueueExecutionRole policy)
42+
- Lambda function (Node.js 22)
43+
- SQS queue
44+
- Event source mapping
45+
- CloudWatch log group (created automatically by Lambda)
46+
47+
## Estimated time
48+
49+
- Run: ~45 seconds
50+
- Cleanup: ~10 seconds
51+
52+
## Cost
53+
54+
Free tier eligible. No charges expected for a few messages.
55+
56+
## Related docs
57+
58+
- [Using Lambda with Amazon SQS](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html)
59+
- [Tutorial: Using Lambda with Amazon SQS](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-example.html)
60+
- [Amazon SQS visibility timeout](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html)
61+
62+
---
63+
64+
## Appendix: Generation details
65+
66+
| Field | Value |
67+
|-------|-------|
68+
| Generation date | 2026-04-14 |
69+
| Source script | Rewritten from internal 084-lambda-sqs-2-cli-script-v2.sh |
70+
| Script test result | EXIT 0, 44s, 7 steps, clean teardown |
71+
| Issues encountered | Original used `set -e` with `log_command` wrapper (replaced with ERR trap); missing `fileb://` for payload (fixed); original used nodejs22.x (kept) |
72+
| Iterations | v1 (internal), v2 (wait-for-active + region fix), v3 (clean rewrite for publish) |

tuts/084-lambda-sqs/lambda-sqs.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Using Lambda with Amazon SQS
2+
3+
This tutorial shows you how to create a Lambda function that processes messages from an Amazon SQS queue. You create the function, test it with a sample event, connect it to an SQS queue, and verify end-to-end message processing.
4+
5+
## Prerequisites
6+
7+
- AWS CLI configured with credentials and a default region
8+
- Permissions to create Lambda functions, IAM roles, and SQS queues
9+
10+
## Step 1: Create an execution role
11+
12+
Create an IAM role with the `AWSLambdaSQSQueueExecutionRole` managed policy, which grants permissions to read from SQS and write logs.
13+
14+
```bash
15+
aws iam create-role --role-name lambda-sqs-role \
16+
--assume-role-policy-document '{
17+
"Version":"2012-10-17",
18+
"Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]
19+
}'
20+
21+
aws iam attach-role-policy --role-name lambda-sqs-role \
22+
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
23+
```
24+
25+
Wait about 10 seconds for the role to propagate.
26+
27+
## Step 2: Create the Lambda function
28+
29+
Create a Node.js function that logs each SQS message body.
30+
31+
```javascript
32+
// index.mjs
33+
export const handler = async (event) => {
34+
for (const message of event.Records) {
35+
console.log(`Processed message: ${message.body}`);
36+
}
37+
return { statusCode: 200 };
38+
};
39+
```
40+
41+
Package and deploy:
42+
43+
```bash
44+
zip function.zip index.mjs
45+
46+
aws lambda create-function --function-name sqs-processor \
47+
--zip-file fileb://function.zip \
48+
--handler index.handler --runtime nodejs22.x \
49+
--role arn:aws:iam::<account-id>:role/lambda-sqs-role \
50+
--architectures x86_64
51+
```
52+
53+
Wait for the function to become active:
54+
55+
```bash
56+
aws lambda wait function-active-v2 --function-name sqs-processor
57+
```
58+
59+
## Step 3: Test with a sample event
60+
61+
Invoke the function with a sample SQS event to verify it works:
62+
63+
```bash
64+
aws lambda invoke --function-name sqs-processor \
65+
--payload fileb://test-event.json \
66+
--cli-binary-format raw-in-base64-out response.json
67+
```
68+
69+
## Step 4: Create an SQS queue
70+
71+
```bash
72+
aws sqs create-queue --queue-name lambda-test-queue
73+
QUEUE_URL=$(aws sqs get-queue-url --queue-name lambda-test-queue --query 'QueueUrl' --output text)
74+
QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url $QUEUE_URL \
75+
--attribute-names QueueArn --query 'Attributes.QueueArn' --output text)
76+
```
77+
78+
## Step 5: Create an event source mapping
79+
80+
Connect the SQS queue to the Lambda function:
81+
82+
```bash
83+
aws lambda create-event-source-mapping \
84+
--function-name sqs-processor \
85+
--batch-size 10 \
86+
--event-source-arn $QUEUE_ARN
87+
```
88+
89+
## Step 6: Send test messages
90+
91+
```bash
92+
aws sqs send-message --queue-url $QUEUE_URL --message-body "Hello from the Lambda-SQS tutorial"
93+
aws sqs send-message --queue-url $QUEUE_URL --message-body "This is message number 2"
94+
```
95+
96+
## Step 7: Verify in CloudWatch Logs
97+
98+
After about 15 seconds, check the function's log output:
99+
100+
```bash
101+
aws logs describe-log-streams --log-group-name /aws/lambda/sqs-processor \
102+
--order-by LastEventTime --descending --limit 1
103+
104+
aws logs get-log-events --log-group-name /aws/lambda/sqs-processor \
105+
--log-stream-name <log-stream-name> \
106+
--query 'events[].message' --output text
107+
```
108+
109+
You should see `Processed message: Hello from the Lambda-SQS tutorial` in the output.
110+
111+
## Cleanup
112+
113+
```bash
114+
aws lambda delete-event-source-mapping --uuid <mapping-uuid>
115+
aws lambda delete-function --function-name sqs-processor
116+
aws sqs delete-queue --queue-url $QUEUE_URL
117+
aws iam detach-role-policy --role-name lambda-sqs-role \
118+
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
119+
aws iam delete-role --role-name lambda-sqs-role
120+
```
121+
122+
The script automates all steps including cleanup. Run it with:
123+
124+
```bash
125+
bash lambda-sqs.sh
126+
```

tuts/084-lambda-sqs/lambda-sqs.sh

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#!/bin/bash
2+
# Tutorial: Using Lambda with Amazon SQS
3+
# Source: https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-example.html
4+
5+
WORK_DIR=$(mktemp -d)
6+
LOG_FILE="$WORK_DIR/lambda-sqs-$(date +%Y%m%d-%H%M%S).log"
7+
exec > >(tee -a "$LOG_FILE") 2>&1
8+
9+
REGION=${AWS_DEFAULT_REGION:-${AWS_REGION:-$(aws configure get region 2>/dev/null)}}
10+
if [ -z "$REGION" ]; then
11+
echo "ERROR: No AWS region configured. Set one with: export AWS_DEFAULT_REGION=us-east-1"
12+
exit 1
13+
fi
14+
export AWS_DEFAULT_REGION="$REGION"
15+
echo "Region: $REGION"
16+
17+
RANDOM_ID=$(openssl rand -hex 4)
18+
ROLE_NAME="lambda-sqs-role-${RANDOM_ID}"
19+
FUNCTION_NAME="sqs-processor-${RANDOM_ID}"
20+
QUEUE_NAME="lambda-tut-queue-${RANDOM_ID}"
21+
22+
handle_error() { echo "ERROR on line $1"; trap - ERR; cleanup; exit 1; }
23+
trap 'handle_error $LINENO' ERR
24+
25+
cleanup() {
26+
echo ""
27+
echo "Cleaning up resources..."
28+
[ -n "$EVENT_SOURCE_UUID" ] && \
29+
aws lambda delete-event-source-mapping --uuid "$EVENT_SOURCE_UUID" 2>/dev/null && echo " Deleted event source mapping"
30+
aws lambda delete-function --function-name "$FUNCTION_NAME" 2>/dev/null && echo " Deleted function $FUNCTION_NAME"
31+
aws iam detach-role-policy --role-name "$ROLE_NAME" \
32+
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole 2>/dev/null
33+
aws iam delete-role --role-name "$ROLE_NAME" 2>/dev/null && echo " Deleted role $ROLE_NAME"
34+
[ -n "$QUEUE_URL" ] && aws sqs delete-queue --queue-url "$QUEUE_URL" 2>/dev/null && echo " Deleted queue $QUEUE_NAME"
35+
aws logs delete-log-group --log-group-name "/aws/lambda/$FUNCTION_NAME" 2>/dev/null && echo " Deleted log group"
36+
rm -rf "$WORK_DIR"
37+
echo "Cleanup complete."
38+
}
39+
40+
# Step 1: Create IAM role
41+
echo "Step 1: Creating IAM role: $ROLE_NAME"
42+
ROLE_ARN=$(aws iam create-role --role-name "$ROLE_NAME" \
43+
--assume-role-policy-document '{
44+
"Version":"2012-10-17",
45+
"Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]
46+
}' --query 'Role.Arn' --output text)
47+
aws iam attach-role-policy --role-name "$ROLE_NAME" \
48+
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
49+
echo " Role ARN: $ROLE_ARN"
50+
echo " Waiting for role propagation..."
51+
sleep 10
52+
53+
# Step 2: Create Lambda function
54+
echo "Step 2: Creating Lambda function: $FUNCTION_NAME"
55+
cat > "$WORK_DIR/index.mjs" << 'EOF'
56+
export const handler = async (event) => {
57+
for (const message of event.Records) {
58+
console.log(`Processed message: ${message.body}`);
59+
}
60+
return { statusCode: 200 };
61+
};
62+
EOF
63+
(cd "$WORK_DIR" && zip function.zip index.mjs > /dev/null)
64+
65+
aws lambda create-function --function-name "$FUNCTION_NAME" \
66+
--zip-file "fileb://$WORK_DIR/function.zip" \
67+
--handler index.handler --runtime nodejs22.x \
68+
--role "$ROLE_ARN" --timeout 30 \
69+
--architectures x86_64 \
70+
--query 'FunctionArn' --output text
71+
72+
echo " Waiting for function to become active..."
73+
aws lambda wait function-active-v2 --function-name "$FUNCTION_NAME"
74+
75+
# Step 3: Test the function with a sample SQS event
76+
echo "Step 3: Testing Lambda with sample SQS event"
77+
cat > "$WORK_DIR/test-event.json" << EOF
78+
{
79+
"Records": [{
80+
"messageId": "test-msg-001",
81+
"body": "Hello from SQS test event",
82+
"attributes": {"ApproximateReceiveCount": "1", "SentTimestamp": "1545082649183"},
83+
"messageAttributes": {},
84+
"md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
85+
"eventSource": "aws:sqs",
86+
"eventSourceARN": "arn:aws:sqs:$REGION:000000000000:test-queue",
87+
"awsRegion": "$REGION"
88+
}]
89+
}
90+
EOF
91+
92+
aws lambda invoke --function-name "$FUNCTION_NAME" \
93+
--payload "fileb://$WORK_DIR/test-event.json" \
94+
--cli-binary-format raw-in-base64-out \
95+
"$WORK_DIR/response.json" > /dev/null
96+
echo " Response: $(cat "$WORK_DIR/response.json")"
97+
98+
# Step 4: Create SQS queue
99+
echo "Step 4: Creating SQS queue: $QUEUE_NAME"
100+
QUEUE_URL=$(aws sqs create-queue --queue-name "$QUEUE_NAME" --query 'QueueUrl' --output text)
101+
QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url "$QUEUE_URL" \
102+
--attribute-names QueueArn --query 'Attributes.QueueArn' --output text)
103+
echo " Queue ARN: $QUEUE_ARN"
104+
105+
# Step 5: Create event source mapping
106+
echo "Step 5: Connecting SQS queue to Lambda"
107+
EVENT_SOURCE_UUID=$(aws lambda create-event-source-mapping \
108+
--function-name "$FUNCTION_NAME" \
109+
--batch-size 10 \
110+
--event-source-arn "$QUEUE_ARN" \
111+
--query 'UUID' --output text)
112+
echo " Event source mapping: $EVENT_SOURCE_UUID"
113+
114+
# Step 6: Send test messages via SQS
115+
echo "Step 6: Sending test messages to SQS"
116+
aws sqs send-message --queue-url "$QUEUE_URL" --message-body "Hello from the Lambda-SQS tutorial" > /dev/null
117+
aws sqs send-message --queue-url "$QUEUE_URL" --message-body "This is message number 2" > /dev/null
118+
echo " Sent 2 messages. Waiting for Lambda to process them..."
119+
sleep 15
120+
121+
# Step 7: Verify in CloudWatch Logs
122+
echo "Step 7: Verifying Lambda processed the messages"
123+
LOG_GROUP="/aws/lambda/$FUNCTION_NAME"
124+
FOUND_LOGS=false
125+
for i in $(seq 1 15); do
126+
LOG_STREAM=$(aws logs describe-log-streams --log-group-name "$LOG_GROUP" \
127+
--order-by LastEventTime --descending --limit 1 \
128+
--query 'logStreams[0].logStreamName' --output text 2>/dev/null || true)
129+
if [ -n "$LOG_STREAM" ] && [ "$LOG_STREAM" != "None" ]; then
130+
echo " Log stream: $LOG_STREAM"
131+
aws logs get-log-events --log-group-name "$LOG_GROUP" \
132+
--log-stream-name "$LOG_STREAM" \
133+
--query 'events[].message' --output text
134+
FOUND_LOGS=true
135+
break
136+
fi
137+
sleep 5
138+
done
139+
if [ "$FOUND_LOGS" = false ]; then
140+
echo " Logs not available yet (this is normal — they can take a minute to appear)"
141+
fi
142+
143+
echo ""
144+
echo "Tutorial complete."
145+
echo "Do you want to clean up all resources? (y/n): "
146+
read -r CHOICE
147+
if [[ "$CHOICE" =~ ^[Yy]$ ]]; then
148+
cleanup
149+
else
150+
echo "Resources left running. Manual cleanup commands:"
151+
echo " aws lambda delete-event-source-mapping --uuid $EVENT_SOURCE_UUID"
152+
echo " aws lambda delete-function --function-name $FUNCTION_NAME"
153+
echo " aws sqs delete-queue --queue-url $QUEUE_URL"
154+
echo " aws iam detach-role-policy --role-name $ROLE_NAME --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole"
155+
echo " aws iam delete-role --role-name $ROLE_NAME"
156+
fi

0 commit comments

Comments
 (0)