如何使用 Lambda 按固定间隔停止和启动 Amazon EC2 实例?
我想通过自动停止和启动 EC2 实例来减少 Amazon Elastic Compute Cloud (Amazon EC2) 使用量。我该如何使用 AWS Lambda 和 Amazon EventBridge 来做到这一点?
简短描述
注意:以下是一个简单的解决方案。若要获得更强大的解决方案,请使用 AWS Instance Scheduler。有关更多信息,请参阅自动启动和停止 AWS 实例。
要使用 Lambda 按固定间隔停止和启动 Amazon EC2 实例,请执行以下操作:
1. 为 Lambda 函数创建自定义 AWS Identity and Access Management (IAM) 策略和执行角色。
2. 创建停止和启动 EC2 实例的 Lambda 函数。
3. 测试 Lambda 函数。
4. 创建按计划触发函数的 EventBridge 规则。
注意:您还可以创建触发 AWS 账户中发生的事件的规则。
解决方法
注意:如果在完成以下步骤后,在启动错误时收到客户端错误,请参阅当我启动带有加密卷的实例时,实例立即停止,并出现“client error on launch(启动时出现客户端错误)”的错误。
获取要停止和启动的 EC2 实例的 ID。然后,请按照以下步骤执行操作。
为 Lambda 函数创建 IAM policy 和执行角色
1. 使用 JSON 策略编辑器创建 IAM 策略。复制下列 JSON 策略文档,并粘贴到策略编辑器中:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "ec2:Start*", "ec2:Stop*" ], "Resource": "*" } ] }
如果出错,使用
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "ec2:Start*", "ec2:Stop*" ], "Resource": "*" } ] }
2. 为 Lambda 创建 IAM 角色。
重要提示:将权限策略附加到 Lambda 时,请确保选择您刚刚创建的 IAM policy。
创建停止和启动 EC2 实例的 Lambda 函数
1. 在 Lambda 控制台中,选择创建函数。
2. 选择 Author from scratch(从头开始创作)。
3. 在基本信息下,添加以下内容:
在函数名称中,输入一个名称,并将其识别为用于停止 EC2 实例的函数。例如,”StopEC2Instances”。
对于 Runtime(运行时),选择 Python 3.9。
在权限下,展开更改原定设置执行角色。
在执行角色下,选择使用现有角色。
在现有角色下,选择所创建的 IAM 角色。
4. 选择创建函数。
5. 在 Code(代码)、Code source(源代码)下,将下列代码复制并粘贴到代码编辑器中的编辑器窗格中(lambda_function)。此代码将停止您识别的 EC2 实例。
示例函数代码 – 停止 EC2 实例
import boto3 region = 'cn-north-1' instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26'] ec2 = boto3.client('ec2', region_name=region) def lambda_handler(event, context): ec2.stop_instances(InstanceIds=instances) print('stopped your instances: ' + str(instances))
重要提示:对于 region (区域),用实例所在的 AWS 区域替换“us-west-1”。对于 instances (实例),将示例 EC2 实例 ID 替换为要停止和启动的特定实例的 ID。
6. 选择 Deploy(部署)。
7. 在 Configuration(配置)选项卡中,选择 General configuration(常规配置),Edit(编辑)。将 Timeout(超时)设为 10 秒,然后选择 Save(保存)。
注意:根据您的使用案例需要配置 Lambda 函数设置。例如,如果要停止和启动多个实例,可能需要不同的 Timeout(超时)和 Memory(内存)值。
8. 重复步骤 1-7 以创建另一个函数。以不同的方式执行以下操作,以使此函数启动 EC2 实例:
在步骤 3 中,输入一个 Function name (函数名称),请不要与之前的函数名称重复。例如,“StartEC2Instances”。
在步骤 5 中,将以下代码复制并粘贴到代码编辑器的编辑器窗格中(lambda_function):
示例函数代码 – 启动 EC2 实例
import boto3 region = 'cn-north-1' instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26'] ec2 = boto3.client('ec2', region_name=region) def lambda_handler(event, context): ec2.start_instances(InstanceIds=instances) print('started your instances: ' + str(instances))
重要提示:对于 region (区域) 和 instances (实例),请使用与代码中用于停止 EC2 实例的值相同的值。
测试 Lambda 函数
1. 在 Lambda 控制台中,选择函数。
2. 选择您创建的函数之一。
3. 选择 Code(代码)选项卡。
4. 在 Code source(代码源)部分中,选择 Test(测试)。
5. 在配置测试事件对话框中,选择创建新测试事件。
6. 输入 Event name(事件名称)。 然后,选择 Create (创建)。
注意:不需要为测试事件更改 JSON 代码,因为函数不使用它。
7. 选择 Test(测试)以运行该函数。
8. 对创建的另一个函数重复步骤 1-6。
提示:您可以在测试前后检查 EC2 实例的状态,以确认函数是否按预期工作。
创建触发 Lambda 函数的 EventBridge 规则
1. 打开 Eventbridge 控制台。
2. 选择创建规则。
3. 输入规则的 Name(名称),例如“StopEC2Instances”。可选择输入 Description(描述)。
4. 在 Define pattern(定义模式)中,选择 Schedule(计划)。
5. 执行以下任意一项操作:
在固定频率为中,输入以分钟、小时或天为单位的时间间隔。
在 Cron 表达式中,输入一个指示 Lambda 何时停止实例的表达式。有关表达式语法的信息,请参阅规则的计划表达式。
注意:Cron 表达式使用 UTC 进行计算。确保针对您的首选时区调整表达式。
6. 在选择目标中,从目标下拉菜单中选择 Lambda 函数。
7. 对于函数,选择停止您的 EC2 实例的函数。
8. 向下滚动并选择创建。
9. 重复步骤 1-8 以创建启动 EC2 实例的规则。以不同的方式执行以下操作:
输入规则的名称,例如 “StartEC2Instances”。
(可选)输入 Description (描述),例如“每天早上 7 点启动 EC2 实例。”
在步骤 5 中,在 Cron 表达式中,输入一个指示 Lambda 何时启动实例的表达式。
在步骤 7 中,对于 Function(函数),选择启动您的 EC2 实例的函数。
来源:https://aws.amazon.com/cn/premiumsupport/knowledge-center/start-stop-lambda-eventbridge/