|
| 1 | +#!/bin/bash |
| 2 | +# Tutorial: Create an EventBridge rule that triggers a Lambda function |
| 3 | +# Source: https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html |
| 4 | + |
| 5 | +WORK_DIR=$(mktemp -d) |
| 6 | +LOG_FILE="$WORK_DIR/eventbridge-$(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 | +RULE_NAME="eb-tut-rule-${RANDOM_ID}" |
| 19 | +FUNCTION_NAME="eb-tut-handler-${RANDOM_ID}" |
| 20 | +ROLE_NAME="eb-tut-role-${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 | + aws events remove-targets --rule "$RULE_NAME" --ids lambda-target > /dev/null 2>&1 && echo " Removed rule target" |
| 29 | + aws events delete-rule --name "$RULE_NAME" 2>/dev/null && echo " Deleted rule $RULE_NAME" |
| 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/AWSLambdaBasicExecutionRole 2>/dev/null |
| 33 | + aws iam delete-role --role-name "$ROLE_NAME" 2>/dev/null && echo " Deleted role $ROLE_NAME" |
| 34 | + aws logs delete-log-group --log-group-name "/aws/lambda/$FUNCTION_NAME" 2>/dev/null && echo " Deleted log group" |
| 35 | + rm -rf "$WORK_DIR" |
| 36 | + echo "Cleanup complete." |
| 37 | +} |
| 38 | + |
| 39 | +# Step 1: Create IAM role |
| 40 | +echo "Step 1: Creating IAM role: $ROLE_NAME" |
| 41 | +ROLE_ARN=$(aws iam create-role --role-name "$ROLE_NAME" \ |
| 42 | + --assume-role-policy-document '{ |
| 43 | + "Version":"2012-10-17", |
| 44 | + "Statement":[{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"sts:AssumeRole"}] |
| 45 | + }' --query 'Role.Arn' --output text) |
| 46 | +aws iam attach-role-policy --role-name "$ROLE_NAME" \ |
| 47 | + --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole |
| 48 | +echo " Role ARN: $ROLE_ARN" |
| 49 | +echo " Waiting for role propagation..." |
| 50 | +sleep 10 |
| 51 | + |
| 52 | +# Step 2: Create Lambda function |
| 53 | +echo "Step 2: Creating Lambda function: $FUNCTION_NAME" |
| 54 | +cat > "$WORK_DIR/index.mjs" << 'EOF' |
| 55 | +export const handler = async (event) => { |
| 56 | + console.log('EventBridge event received:', JSON.stringify(event, null, 2)); |
| 57 | + return { statusCode: 200, body: 'Event processed' }; |
| 58 | +}; |
| 59 | +EOF |
| 60 | +(cd "$WORK_DIR" && zip function.zip index.mjs > /dev/null) |
| 61 | + |
| 62 | +aws lambda create-function --function-name "$FUNCTION_NAME" \ |
| 63 | + --zip-file "fileb://$WORK_DIR/function.zip" \ |
| 64 | + --handler index.handler --runtime nodejs22.x \ |
| 65 | + --role "$ROLE_ARN" --timeout 30 \ |
| 66 | + --architectures x86_64 \ |
| 67 | + --query 'FunctionArn' --output text |
| 68 | +aws lambda wait function-active-v2 --function-name "$FUNCTION_NAME" |
| 69 | +FUNCTION_ARN=$(aws lambda get-function --function-name "$FUNCTION_NAME" --query 'Configuration.FunctionArn' --output text) |
| 70 | + |
| 71 | +# Step 3: Create EventBridge rule (runs every minute) |
| 72 | +echo "Step 3: Creating EventBridge rule: $RULE_NAME (every 1 minute)" |
| 73 | +RULE_ARN=$(aws events put-rule --name "$RULE_NAME" \ |
| 74 | + --schedule-expression "rate(1 minute)" \ |
| 75 | + --state ENABLED \ |
| 76 | + --query 'RuleArn' --output text) |
| 77 | +echo " Rule ARN: $RULE_ARN" |
| 78 | + |
| 79 | +# Step 4: Grant EventBridge permission to invoke Lambda |
| 80 | +echo "Step 4: Granting EventBridge permission to invoke Lambda" |
| 81 | +aws lambda add-permission --function-name "$FUNCTION_NAME" \ |
| 82 | + --statement-id eb-invoke --action lambda:InvokeFunction \ |
| 83 | + --principal events.amazonaws.com --source-arn "$RULE_ARN" > /dev/null |
| 84 | + |
| 85 | +# Step 5: Add Lambda as target |
| 86 | +echo "Step 5: Adding Lambda as rule target" |
| 87 | +aws events put-targets --rule "$RULE_NAME" \ |
| 88 | + --targets "Id=lambda-target,Arn=$FUNCTION_ARN" > /dev/null |
| 89 | +echo " Target added" |
| 90 | + |
| 91 | +# Step 6: Wait for the rule to fire and check logs |
| 92 | +echo "Step 6: Waiting for EventBridge to trigger Lambda (~60s)..." |
| 93 | +sleep 65 |
| 94 | + |
| 95 | +LOG_GROUP="/aws/lambda/$FUNCTION_NAME" |
| 96 | +FOUND_LOGS=false |
| 97 | +for i in $(seq 1 10); do |
| 98 | + LOG_STREAM=$(aws logs describe-log-streams --log-group-name "$LOG_GROUP" \ |
| 99 | + --order-by LastEventTime --descending --limit 1 \ |
| 100 | + --query 'logStreams[0].logStreamName' --output text 2>/dev/null || true) |
| 101 | + if [ -n "$LOG_STREAM" ] && [ "$LOG_STREAM" != "None" ]; then |
| 102 | + echo " Log stream: $LOG_STREAM" |
| 103 | + echo " Recent events:" |
| 104 | + aws logs get-log-events --log-group-name "$LOG_GROUP" \ |
| 105 | + --log-stream-name "$LOG_STREAM" --limit 5 \ |
| 106 | + --query 'events[].message' --output text |
| 107 | + FOUND_LOGS=true |
| 108 | + break |
| 109 | + fi |
| 110 | + sleep 5 |
| 111 | +done |
| 112 | +if [ "$FOUND_LOGS" = false ]; then |
| 113 | + echo " Logs not available yet — the rule may not have fired yet" |
| 114 | +fi |
| 115 | + |
| 116 | +echo "" |
| 117 | +echo "Tutorial complete." |
| 118 | +echo "Do you want to clean up all resources? (y/n): " |
| 119 | +read -r CHOICE |
| 120 | +if [[ "$CHOICE" =~ ^[Yy]$ ]]; then |
| 121 | + cleanup |
| 122 | +else |
| 123 | + echo "Resources left running. The rule fires every minute." |
| 124 | + echo "Manual cleanup:" |
| 125 | + echo " aws events remove-targets --rule $RULE_NAME --ids lambda-target" |
| 126 | + echo " aws events delete-rule --name $RULE_NAME" |
| 127 | + echo " aws lambda delete-function --function-name $FUNCTION_NAME" |
| 128 | + echo " aws iam detach-role-policy --role-name $ROLE_NAME --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" |
| 129 | + echo " aws iam delete-role --role-name $ROLE_NAME" |
| 130 | +fi |
0 commit comments