如何用YAML配置AWS Lambda触发邮件?SQS能否替代SES/SNS发邮件?
Hey there! Let's break down your questions and get you sorted out.
1. How to Configure AWS Lambda to Trigger Emails Using YAML
To set up AWS Lambda to send emails (most commonly via Amazon SES), you can use a CloudFormation YAML template to define all required resources—Lambda function, IAM permissions, triggers, and SES integration. Here's a step-by-step breakdown:
Step 1: Create an IAM Role for Lambda
First, define an IAM role that lets Lambda call SES and access necessary logging resources:
Resources: LambdaEmailRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: LambdaEmailPermissions PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ses:SendEmail - ses:SendRawEmail Resource: "*" # Restrict to your verified SES identity for security - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: "arn:aws:logs:*:*:*"
Step 2: Define the Lambda Function
Next, create the Lambda function with code that handles email sending via SES. You can inline the code or reference a ZIP file:
EmailSenderLambda: Type: AWS::Lambda::Function Properties: Handler: index.lambda_handler Runtime: python3.11 Role: !GetAtt LambdaEmailRole.Arn Code: ZipFile: | import boto3 import json ses = boto3.client('ses', region_name='eu-west-1') def lambda_handler(event, context): # Extract email details (customize based on your trigger input) to_email = "user@gmail.com" subject = "Lambda Triggered Security Alert" body = "This is an automated email sent by AWS Lambda via Amazon SES." try: response = ses.send_email( Source="your-verified-ses-email@example.com", Destination={'ToAddresses': [to_email]}, Message={ 'Subject': {'Data': subject}, 'Body': {'Text': {'Data': body}} } ) return {'statusCode': 200, 'message': 'Email sent successfully'} except Exception as e: return {'statusCode': 500, 'error': str(e)}
Step 3: Add a Trigger (Optional)
If you want Lambda to run on a schedule (like your existing periodic policy), add a CloudWatch Events trigger:
LambdaScheduleTrigger: Type: AWS::Events::Rule Properties: ScheduleExpression: cron(30/10 10 * * ? *) Targets: - Arn: !GetAtt EmailSenderLambda.Arn Id: "LambdaEmailTarget" LambdaPermissionForEvents: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref EmailSenderLambda Action: lambda:InvokeFunction Principal: events.amazonaws.com SourceArn: !GetAtt LambdaScheduleTrigger.Arn
2. Can SQS Replace SES/SNS for Triggering Emails? (Troubleshooting Your Setup)
Short answer: No, SQS can’t directly send emails on its own. Here’s why your current setup isn’t working, and how to fix it:
Why You’re Not Getting Emails
Your existing YAML policy sends notification messages to an SQS queue—but SQS is just a message storage service. It doesn’t process messages or send emails. The messages are sitting in the queue because there’s no "consumer" (like a Lambda function) reading them and triggering email delivery via SES/SNS.
How to Make SQS Work with Email
To use SQS in your email workflow, you need to add a Lambda consumer that:
- Listens for new messages in your SQS queue
- Extracts email details (recipient, subject, body) from the queue message
- Calls Amazon SES to send the actual email
Step 1: Update Lambda’s IAM Permissions
Add SQS access to your Lambda role so it can read and delete messages:
- Effect: Allow Action: - sqs:ReceiveMessage - sqs:DeleteMessage - sqs:GetQueueAttributes Resource: "arn:aws:sqs:eu-west-1:91*******/queuename"
Step 2: Link Lambda to SQS
Configure SQS as an event source for your Lambda function (so it runs automatically when messages arrive):
SQSEventSourceMapping: Type: AWS::Lambda::EventSourceMapping Properties: BatchSize: 10 EventSourceArn: "arn:aws:sqs:eu-west-1:91*******/queuename" FunctionName: !Ref EmailSenderLambda
Step 3: Modify Lambda Code to Process SQS Messages
Update your Lambda code to parse the message payload from your notify action:
def lambda_handler(event, context): sqs = boto3.client('sqs', region_name='eu-west-1') queue_url = "https://sqs.eu-west-1.amazonaws.com/91*******/queuename" for record in event['Records']: try: # Parse the SQS message body (matches your policy's notify content) message_body = json.loads(record['body']) to_email = message_body['to'][0] subject = message_body['subject'] violation_desc = message_body['violation_desc'] action_desc = message_body['action_desc'] # Compose the email body email_body = f"{violation_desc}\n\n{action_desc}" # Send email via SES ses.send_email( Source="your-verified-ses-email@example.com", Destination={'ToAddresses': [to_email]}, Message={ 'Subject': {'Data': subject}, 'Body': {'Text': {'Data': email_body}} } ) # Delete the processed message from SQS sqs.delete_message( QueueUrl=queue_url, ReceiptHandle=record['receiptHandle'] ) except Exception as e: print(f"Failed to process message: {str(e)}") return {'statusCode': 200, 'message': 'Processed SQS messages'}
Key Takeaway
SQS is great for decoupling your policy’s notification trigger from email delivery, but it needs a middleman (like Lambda) to connect it to SES. SES is the service designed for reliable email sending—you can’t replace it with SQS directly.
内容的提问来源于stack exchange,提问作者Saikiran

