随着时间的推移,AWS 账户可能会积累不再需要的资源,但会继续产生成本。一个常见的例子是删除卷后留下的孤立 EBS 快照。手动管理这些快照可能非常繁琐且成本高昂。
本指南介绍如何在 AWS Lambda 函数中使用 Python (Boto3) 和 Terraform 自动清理孤立的 EBS 快照,然后根据计划或事件使用 AWS EventBridge 触发清理。
最终,您将拥有完整的无服务器解决方案,以保持 AWS 环境清洁且经济高效。
首先,让我们确保安装了必要的工具。
AWS CLI
AWS CLI 允许通过命令行访问 AWS 服务。根据您的操作系统安装:
macOS:brew install awscli
Windows: AWS CLI 安装程序
Linux: 使用包管理器(例如,对于 Ubuntu 为 sudo apt install awscli)。
验证安装:
aws --version
地形
Terraform 是一种流行的基础设施即代码 (IaC) 工具,用于定义和管理 AWS 资源。
macOS:brew install terraform
Windows: Terraform 安装程序
Linux: 下载二进制文件并将其移至 /usr/local/bin。
验证安装:
terraform -version
使用访问密钥配置您的 AWS CLI,以允许 Terraform 和 Lambda 使用 AWS 服务进行身份验证。
从您的 AWS 账户(AWS IAM 控制台)获取访问密钥。
配置 AWS CLI:
aws configure
按照提示输入您的访问密钥、秘密访问密钥、默认区域(例如 us-east-1)和输出格式(例如 json)。
此处提供了创建 Lambda 函数的分步说明。
此 Lambda 函数使用 AWS 的 Python SDK Boto3 来列出所有 EBS 快照,检查其关联的卷状态,并删除卷不再可用的快照。完整的功能代码如下:
import boto3 import logging logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): ec2_cli = boto3.client("ec2") response = ec2_cli.describe_snapshots(OwnerIds=["self"], DryRun=False) snapshot_id = [] for each_snapshot in response["Snapshots"]: try: volume_stat = ec2_cli.describe_volume_status( VolumeIds=[each_snapshot["VolumeId"]], DryRun=False ) except ec2_cli.exceptions.ClientError as e: if e.response["Error"]["Code"] == "InvalidVolume.NotFound": snapshot_id.append(each_snapshot["SnapshotId"]) else: raise e if snapshot_id: for each_snap in snapshot_id: try: ec2_cli.delete_snapshot(SnapshotId=each_snap) logger.info(f"Deleted SnapshotId {each_snap}") except ec2_cli.exceptions.ClientError as e: return { "statusCode": 500, "body": f"Error deleting snapshot {each_snap}: {e}", } return {"statusCode": 200}
使用 Terraform,我们将创建 Lambda 函数、IAM 角色和策略以将此脚本部署到 AWS。此外,我们将设置一个 EventBridge 规则来定期触发 Lambda。
Terraform 设置和提供程序配置
本部分配置 Terraform,包括在 S3 中设置远程状态管理。
注意: 根据 terraform -version 输出更改 required_version 值。
aws --version
Lambda 的 IAM 角色和策略
此 IAM 配置为 Lambda 设置访问 EC2 和 CloudWatch 的权限,从而启用快照删除和日志记录。
terraform -version
打包和部署 Lambda 函数
在这里,我们打包 Python 代码并将其部署为 Lambda 函数。
aws configure
Lambda 调用的 EventBridge 规则
AWS EventBridge 允许您为 Lambda 函数创建计划触发器或基于事件的触发器。在这里,我们将配置 EventBridge 以按计划(例如每 24 小时)调用我们的 Lambda 函数。您可以在此处的 AWS 文档中了解有关 EventBridge 和计划事件的更多信息。
import boto3 import logging logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): ec2_cli = boto3.client("ec2") response = ec2_cli.describe_snapshots(OwnerIds=["self"], DryRun=False) snapshot_id = [] for each_snapshot in response["Snapshots"]: try: volume_stat = ec2_cli.describe_volume_status( VolumeIds=[each_snapshot["VolumeId"]], DryRun=False ) except ec2_cli.exceptions.ClientError as e: if e.response["Error"]["Code"] == "InvalidVolume.NotFound": snapshot_id.append(each_snapshot["SnapshotId"]) else: raise e if snapshot_id: for each_snap in snapshot_id: try: ec2_cli.delete_snapshot(SnapshotId=each_snap) logger.info(f"Deleted SnapshotId {each_snap}") except ec2_cli.exceptions.ClientError as e: return { "statusCode": 500, "body": f"Error deleting snapshot {each_snap}: {e}", } return {"statusCode": 200}
定义基础设施后,初始化并应用 Terraform 配置:
terraform { required_version = ">=1.5.6" required_providers { aws = { source = "hashicorp/aws" version = "~> 5.72.0" } } backend "s3" { bucket = "terraform-state-files-0110" key = "delete-orphan-snapshots/terraform.tfstate" region = "us-east-1" dynamodb_table = "tf_state_file_locking" } } provider "aws" { region = "us-east-1" }
验证解决方案是否有效:
总结
通过结合 Python (Boto3)、Terraform 和 AWS EventBridge,我们创建了一个完全自动化、无服务器的解决方案来清理孤立的 EBS 快照。这种设置不仅降低了云成本,还促进了整洁、高效的 AWS 环境。通过计划调用,您可以放心,孤立资源将始终被删除。
在您自己的 AWS 账户中尝试此解决方案,体验云资源管理自动化的优势!
以上是告别孤立快照:使用 Serverless、Terraform 和 AWS EventBridge 自动清理!的详细内容。更多信息请关注PHP中文网其他相关文章!