如何配置AWS可用状态EBS卷的每日邮件告警?
How to Monitor Unattached (Available) EBS Volumes & Get Daily Email Alerts with AWS Tools
Got it, let's walk through exactly how to set this up using AWS CloudWatch EventBridge (formerly CloudWatch Events), Lambda, and SNS—this is a super common cleanup use case, so it's straightforward once you piece the parts together. Here's the step-by-step breakdown:
1. First, Create an SNS Topic for Email Notifications
You need a reliable way to send alerts, so AWS SNS (Simple Notification Service) is perfect for this:
- Head to the SNS Console, click Create topic. Choose "Standard" type (it's free and works perfectly for this use case).
- Name your topic something like
UnattachedEBSAlerts, then click Create topic. - Once the topic is created, go to the Subscriptions tab, click Create subscription.
- For Protocol, select Email.
- For Endpoint, enter your email address.
- Click Create subscription, then check your inbox—AWS will send a verification email; you need to click the link to confirm the subscription (otherwise alerts won't come through).
2. Build a Lambda Function to Check for Unattached EBS Volumes
Lambda will handle the actual logic of querying EC2 for Available volumes and triggering the alert:
- Go to the Lambda Console, click Create function. Choose "Author from scratch".
- Name your function
CheckUnattachedEBSVolumes. - Pick Python 3.11 (or any recent Python runtime—Python is great for quick AWS API scripts).
- Click Create function.
- Name your function
- Replace the default code in the code editor with this script:
import boto3 import os from botocore.exceptions import ClientError def lambda_handler(event, context): # Initialize AWS clients ec2 = boto3.client('ec2', region_name=os.environ['REGION']) sns = boto3.client('sns') sns_topic_arn = os.environ['SNS_TOPIC_ARN'] # Query all EBS volumes with "Available" status try: response = ec2.describe_volumes( Filters=[{'Name': 'status', 'Values': ['available']}] ) except ClientError as e: print(f"Error fetching volumes: {e.response['Error']['Message']}") return {'statusCode': 500, 'body': 'Failed to retrieve volume data'} unattached_volumes = response['Volumes'] if len(unattached_volumes) > 0: # Build a human-readable alert message alert_message = f"⚠️ Found {len(unattached_volumes)} unattached EBS volumes (status: Available):\n\n" for vol in unattached_volumes: alert_message += ( f"- Volume ID: {vol['VolumeId']}\n" f" Size: {vol['Size']} GiB\n" f" Created: {vol['CreateTime'].strftime('%Y-%m-%d %H:%M:%S UTC')}\n\n" ) # Send the alert via SNS try: sns.publish( TopicArn=sns_topic_arn, Subject="Unattached EBS Volume Alert", Message=alert_message ) return {'statusCode': 200, 'body': f"Alert sent for {len(unattached_volumes)} volumes"} except ClientError as e: print(f"Error sending alert: {e.response['Error']['Message']}") return {'statusCode': 500, 'body': 'Failed to send alert'} else: return {'statusCode': 200, 'body': 'No unattached EBS volumes found'}
- Now add environment variables to the Lambda function:
- Go to the Configuration tab, select Environment variables, click Edit.
- Add two variables:
REGION: Set to your AWS region (e.g.,eu-west-1)SNS_TOPIC_ARN: Paste the ARN of the SNS topic you created earlier (you can copy this from the SNS topic's details page)
- Give Lambda permissions to access EC2 and SNS:
- Still in Configuration, go to Permissions, click the link under Execution role (this takes you to the IAM console).
- In the IAM role page, go to Permissions, click Add permissions > Attach policies.
- Search for and attach
AmazonEC2ReadOnlyAccess(so Lambda can list volumes) andAmazonSNSFullAccess(or create a more restrictive policy if you want, but this works for testing).
3. Set Up a CloudWatch EventBridge Rule to Trigger Lambda Daily
This is how you make the check run automatically every day:
- Go to the CloudWatch Console, navigate to Events > Rules (or search for EventBridge directly), click Create rule.
- Name your rule
DailyEBSVolumeCheck, add a description like "Daily check for unattached EBS volumes". - Under Schedule pattern, select A schedule that runs at a regular rate and set it to
1 day. Or, if you want a specific time (e.g., 8 AM UTC), use a Cron expression like0 8 * * ? *(AWS Cron format isminute hour day month year week). - Under Targets, click Add target, select Lambda function, then choose your
CheckUnattachedEBSVolumesfunction. - Click Create rule to finish.
- Name your rule
4. Test It Out
To make sure everything works as expected:
- Go back to Lambda, click Test. Create a test event (name it whatever, use the default
{}as the payload), then click Test. - If you have any
AvailableEBS volumes, you should get an email within a minute. If not, the Lambda execution log will show "No unattached EBS volumes found". - You can also temporarily adjust the EventBridge rule to run every minute to test the schedule, then switch it back to daily once you confirm it works.
Quick Tips for Optimization
- Restrict Permissions: Instead of using
AmazonSNSFullAccess, create a custom IAM policy that only allows Lambda to publish to your specific SNS topic—this follows the principle of least privilege. - Multi-Region Monitoring: If you use multiple AWS regions, modify the Lambda function to loop through a list of regions, or replicate this setup in each region.
- Add Volume Tags: If you want to exclude certain tagged volumes (e.g., "retain: true"), update the
describe_volumesfilters to exclude those tags.
内容的提问来源于stack exchange,提问作者Techboy
相关产品推荐
相关产品推荐

