Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions tuts/093-amazon-eventbridge-gs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# EventBridge: Schedule a Lambda function

Create an EventBridge scheduled rule that invokes a Lambda function every minute, verify execution in CloudWatch Logs, and clean up.

## Source

https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html

## Use case

- ID: eventbridge/getting-started
- Phase: create
- Complexity: beginner
- Core actions: events:PutRule, events:PutTargets

## What it does

1. Creates an IAM execution role for Lambda
2. Creates a Node.js Lambda function that logs EventBridge events
3. Creates an EventBridge rule with a `rate(1 minute)` schedule
4. Grants EventBridge permission to invoke the function
5. Adds the Lambda function as the rule target
6. Waits for the rule to fire and verifies output in CloudWatch Logs

## Running

```bash
bash amazon-eventbridge-gs.sh
```

To auto-run with cleanup:

```bash
echo 'y' | bash amazon-eventbridge-gs.sh
```

## Resources created

- EventBridge rule (scheduled, rate 1 minute)
- Lambda function (Node.js 22)
- IAM role (with AWSLambdaBasicExecutionRole policy)
- CloudWatch log group (created automatically by Lambda)

## Estimated time

- Run: ~90 seconds (includes 65s wait for rule to fire)
- Cleanup: ~5 seconds

## Cost

Free tier eligible. Lambda and EventBridge invocations stay well within free tier limits for this tutorial.

## Related docs

- [Getting started with Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html)
- [Creating a rule that runs on a schedule](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html)
- [Tutorial: Use EventBridge to relay events to a Lambda function](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-log-ec2-instance-state.html)
- [Schedule expressions using rate or cron](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-scheduled-rule-pattern.html)
8 changes: 8 additions & 0 deletions tuts/093-amazon-eventbridge-gs/REVISION-HISTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Revision History: 093-amazon-eventbridge-gs

## Shell (CLI script)

### 2026-04-14 v1 published
- Type: functional
- Initial version

125 changes: 125 additions & 0 deletions tuts/093-amazon-eventbridge-gs/amazon-eventbridge-gs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Create an EventBridge rule that triggers a Lambda function on a schedule

This tutorial shows you how to create an Amazon EventBridge scheduled rule that invokes an AWS Lambda function every minute. You create the Lambda function, set up the rule, verify the function runs by checking CloudWatch Logs, and then clean up.

## Prerequisites

- AWS CLI configured with credentials and a default region
- Permissions to create EventBridge rules, Lambda functions, and IAM roles

## Step 1: Create an execution role

Create an IAM role that grants the Lambda function permission to write logs.

```bash
ROLE_ARN=$(aws iam create-role --role-name eb-tut-role \
--assume-role-policy-document '{
"Version":"2012-10-17",
"Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]
}' --query 'Role.Arn' --output text)

aws iam attach-role-policy --role-name eb-tut-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
```

Wait about 10 seconds for the role to propagate before creating the function.

## Step 2: Create the Lambda function

Create a Node.js function that logs each EventBridge event it receives.

```javascript
// index.mjs
export const handler = async (event) => {
console.log('EventBridge event received:', JSON.stringify(event, null, 2));
return { statusCode: 200, body: 'Event processed' };
};
```

Package and deploy:

```bash
zip function.zip index.mjs

aws lambda create-function --function-name eb-tut-handler \
--zip-file fileb://function.zip \
--handler index.handler --runtime nodejs22.x \
--role $ROLE_ARN --timeout 30 \
--architectures x86_64
```

Wait for the function to become active:

```bash
aws lambda wait function-active-v2 --function-name eb-tut-handler
```

## Step 3: Create an EventBridge scheduled rule

Create a rule that fires every minute.

```bash
RULE_ARN=$(aws events put-rule --name eb-tut-rule \
--schedule-expression "rate(1 minute)" \
--state ENABLED \
--query 'RuleArn' --output text)
```

## Step 4: Grant EventBridge permission to invoke Lambda

Add a resource-based policy that allows EventBridge to call the function.

```bash
aws lambda add-permission --function-name eb-tut-handler \
--statement-id eb-invoke --action lambda:InvokeFunction \
--principal events.amazonaws.com --source-arn $RULE_ARN
```

## Step 5: Add the Lambda function as a target

Attach the function to the rule so EventBridge invokes it on each trigger.

```bash
FUNCTION_ARN=$(aws lambda get-function --function-name eb-tut-handler \
--query 'Configuration.FunctionArn' --output text)

aws events put-targets --rule eb-tut-rule \
--targets "Id=lambda-target,Arn=$FUNCTION_ARN"
```

## Step 6: Verify in CloudWatch Logs

Wait about 60 seconds for the rule to fire, then check the function's log output:

```bash
aws logs describe-log-streams \
--log-group-name /aws/lambda/eb-tut-handler \
--order-by LastEventTime --descending --limit 1

aws logs get-log-events \
--log-group-name /aws/lambda/eb-tut-handler \
--log-stream-name <log-stream-name> \
--query 'events[].message' --output text
```

You should see `EventBridge event received:` followed by the scheduled event JSON, which includes `"source": "aws.events"` and `"detail-type": "Scheduled Event"`.

## Cleanup

Delete all resources in reverse order:

```bash
aws events remove-targets --rule eb-tut-rule --ids lambda-target
aws events delete-rule --name eb-tut-rule
aws lambda delete-function --function-name eb-tut-handler
aws iam detach-role-policy --role-name eb-tut-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
aws iam delete-role --role-name eb-tut-role
aws logs delete-log-group --log-group-name /aws/lambda/eb-tut-handler
```

The script automates all steps including cleanup. Run it with:

```bash
bash amazon-eventbridge-gs.sh
```
130 changes: 130 additions & 0 deletions tuts/093-amazon-eventbridge-gs/amazon-eventbridge-gs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/bin/bash
# Tutorial: Create an EventBridge rule that triggers a Lambda function
# Source: https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html

WORK_DIR=$(mktemp -d)
LOG_FILE="$WORK_DIR/eventbridge-$(date +%Y%m%d-%H%M%S).log"
exec > >(tee -a "$LOG_FILE") 2>&1

REGION=${AWS_DEFAULT_REGION:-${AWS_REGION:-$(aws configure get region 2>/dev/null)}}
if [ -z "$REGION" ]; then
echo "ERROR: No AWS region configured. Set one with: export AWS_DEFAULT_REGION=us-east-1"
exit 1
fi
export AWS_DEFAULT_REGION="$REGION"
echo "Region: $REGION"

RANDOM_ID=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 8 | head -n 1)
RULE_NAME="eb-tut-rule-${RANDOM_ID}"
FUNCTION_NAME="eb-tut-handler-${RANDOM_ID}"
ROLE_NAME="eb-tut-role-${RANDOM_ID}"

handle_error() { echo "ERROR on line $1"; trap - ERR; cleanup; exit 1; }
trap 'handle_error $LINENO' ERR

cleanup() {
echo ""
echo "Cleaning up resources..."
aws events remove-targets --rule "$RULE_NAME" --ids lambda-target > /dev/null 2>&1 && echo " Removed rule target"
aws events delete-rule --name "$RULE_NAME" 2>/dev/null && echo " Deleted rule $RULE_NAME"
aws lambda delete-function --function-name "$FUNCTION_NAME" 2>/dev/null && echo " Deleted function $FUNCTION_NAME"
aws iam detach-role-policy --role-name "$ROLE_NAME" \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 2>/dev/null
aws iam delete-role --role-name "$ROLE_NAME" 2>/dev/null && echo " Deleted role $ROLE_NAME"
aws logs delete-log-group --log-group-name "/aws/lambda/$FUNCTION_NAME" 2>/dev/null && echo " Deleted log group"
rm -rf "$WORK_DIR"
echo "Cleanup complete."
}

# Step 1: Create IAM role
echo "Step 1: Creating IAM role: $ROLE_NAME"
ROLE_ARN=$(aws iam create-role --role-name "$ROLE_NAME" \
--assume-role-policy-document '{
"Version":"2012-10-17",
"Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}]
}' --query 'Role.Arn' --output text)
aws iam attach-role-policy --role-name "$ROLE_NAME" \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
echo " Role ARN: $ROLE_ARN"
echo " Waiting for role propagation..."
sleep 10

# Step 2: Create Lambda function
echo "Step 2: Creating Lambda function: $FUNCTION_NAME"
cat > "$WORK_DIR/index.mjs" << 'EOF'
export const handler = async (event) => {
console.log('EventBridge event received:', JSON.stringify(event, null, 2));
return { statusCode: 200, body: 'Event processed' };
};
EOF
(cd "$WORK_DIR" && zip function.zip index.mjs > /dev/null)

aws lambda create-function --function-name "$FUNCTION_NAME" \
--zip-file "fileb://$WORK_DIR/function.zip" \
--handler index.handler --runtime nodejs22.x \
--role "$ROLE_ARN" --timeout 30 \
--architectures x86_64 \
--query 'FunctionArn' --output text
aws lambda wait function-active-v2 --function-name "$FUNCTION_NAME"
FUNCTION_ARN=$(aws lambda get-function --function-name "$FUNCTION_NAME" --query 'Configuration.FunctionArn' --output text)

# Step 3: Create EventBridge rule (runs every minute)
echo "Step 3: Creating EventBridge rule: $RULE_NAME (every 1 minute)"
RULE_ARN=$(aws events put-rule --name "$RULE_NAME" \
--schedule-expression "rate(1 minute)" \
--state ENABLED \
--query 'RuleArn' --output text)
echo " Rule ARN: $RULE_ARN"

# Step 4: Grant EventBridge permission to invoke Lambda
echo "Step 4: Granting EventBridge permission to invoke Lambda"
aws lambda add-permission --function-name "$FUNCTION_NAME" \
--statement-id eb-invoke --action lambda:InvokeFunction \
--principal events.amazonaws.com --source-arn "$RULE_ARN" > /dev/null

# Step 5: Add Lambda as target
echo "Step 5: Adding Lambda as rule target"
aws events put-targets --rule "$RULE_NAME" \
--targets "Id=lambda-target,Arn=$FUNCTION_ARN" > /dev/null
echo " Target added"

# Step 6: Wait for the rule to fire and check logs
echo "Step 6: Waiting for EventBridge to trigger Lambda (~60s)..."
sleep 65

LOG_GROUP="/aws/lambda/$FUNCTION_NAME"
FOUND_LOGS=false
for i in $(seq 1 10); do
LOG_STREAM=$(aws logs describe-log-streams --log-group-name "$LOG_GROUP" \
--order-by LastEventTime --descending --limit 1 \
--query 'logStreams[0].logStreamName' --output text 2>/dev/null || true)
if [ -n "$LOG_STREAM" ] && [ "$LOG_STREAM" != "None" ]; then
echo " Log stream: $LOG_STREAM"
echo " Recent events:"
aws logs get-log-events --log-group-name "$LOG_GROUP" \
--log-stream-name "$LOG_STREAM" --limit 5 \
--query 'events[].message' --output text
FOUND_LOGS=true
break
fi
sleep 5
done
if [ "$FOUND_LOGS" = false ]; then
echo " Logs not available yet — the rule may not have fired yet"
fi

echo ""
echo "Tutorial complete."
echo "Do you want to clean up all resources? (y/n): "
read -r CHOICE
if [[ "$CHOICE" =~ ^[Yy]$ ]]; then
cleanup
else
echo "Resources left running. The rule fires every minute."
echo "Manual cleanup:"
echo " aws events remove-targets --rule $RULE_NAME --ids lambda-target"
echo " aws events delete-rule --name $RULE_NAME"
echo " aws lambda delete-function --function-name $FUNCTION_NAME"
echo " aws iam detach-role-policy --role-name $ROLE_NAME --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
echo " aws iam delete-role --role-name $ROLE_NAME"
fi
58 changes: 58 additions & 0 deletions tuts/110-amazon-sqs-gs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# SQS: Create queues and send messages

## Source

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-getting-started.html

## Use case

- **ID**: sqs/getting-started
- **Level**: beginner
- **Core actions**: `sqs:CreateQueue`, `sqs:SendMessage`

## Steps

1. Create a standard queue
2. Create a dead-letter queue and configure redrive policy
3. Send messages (individual and batch)
4. Receive and process messages
5. Delete processed messages
6. Check queue attributes
7. Create a FIFO queue and send a message

## Resources created

| Resource | Type |
|----------|------|
| `tut-queue-<random>` | Standard queue |
| `tut-dlq-<random>` | Dead-letter queue |
| `tut-fifo-<random>.fifo` | FIFO queue |

## Cost

Free tier includes 1 million requests/month. This tutorial sends fewer than 10 messages.

## Duration

~14 seconds

## Related docs

- [Getting started with Amazon SQS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-getting-started.html)
- [Amazon SQS dead-letter queues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html)
- [Amazon SQS FIFO queues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html)
- [Sending messages in batches](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-batch-api-actions.html)

---

## Appendix

| Field | Value |
|-------|-------|
| Date | 2026-04-14 |
| Script lines | 110 |
| Exit code | 0 |
| Runtime | 14s |
| Steps | 7 |
| Issues | Fixed f-string quoting |
| Version | v1 |
8 changes: 8 additions & 0 deletions tuts/110-amazon-sqs-gs/REVISION-HISTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Revision History: 110-amazon-sqs-gs

## Shell (CLI script)

### 2026-04-14 v1 published
- Type: functional
- Initial version

Loading
Loading