如何使用 Lambda 按固定间隔停止和启动 Amazon EC2 实例?

上次更新时间:2019 年 6 月 28 日

我希望通过自动停止和启动 EC2 实例,从而降低我的 Amazon Elastic Compute Cloud (Amazon EC2) 使用量。如何使用 AWS Lambda 和 Amazon CloudWatch Events 来实现此目的?

简要说明

注意:此示例设置是非常简单的解决方案。有关更可靠的解决方案,请使用 AWS 实例计划程序

如需完成此设置,请执行以下操作:

1.    为 Lambda 函数创建自定义 AWS Identity and Access Management (IAM) 策略和执行角色。

2.    创建停止和启动 EC2 实例的 Lambda 函数。

3.    创建按计划触发您的函数的 CloudWatch Events 规则。例如,您可以创建一个规则,在夜间停止您的 EC2 实例,并创建另一个规则,在早上重新启动实例。

注意:您也可以创建当您 AWS 账户中发生某事件时触发的规则

解决方法

获取您想停止或启动的 EC2 实例的 ID,然后按照以下说明操作。

创建 IAM 策略和角色

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": "*"
    }
  ]
}

2.    为 Lambda 创建一个 IAM 角色。附加权限策略时,搜索并选择您创建的 IAM 策略。

创建停止和启动 EC2 实例的 Lambda 函数

1.    在 Lambda 控制台中,选择创建函数

2.    选择 Author from scratch (从头开始创作)

3.    在基本信息中下,添加以下内容:
对于函数名,输入一个名称,该名称将其识别为用于停止 EC2 实例的函数。例如“StopEC2Instances”。
对于运行时,请选择 Python 2.7
权限下,展开选择或创建执行角色
执行角色下,选择使用现有角色
现有角色下,选择您创建的 IAM 角色。

4.    选择创建函数

5.    复制此代码,然后在函数代码下,将其粘贴到代码编辑器的编辑器窗格 (lambda_function) 中。此代码将停止您指定的 EC2 实例。

注意:对于区域,使用实例所在的 AWS 区域替换“us-west-1”。对于实例,使用要停止和启动的特定实例的 ID,来替换示例 EC2 实例的 ID。

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.stop_instances(InstanceIds=instances)
    print 'stopped your instances: ' + str(instances)

6.    在基本设置下,将超时设置为 10 秒。

注意:请根据您所用案例的需要配置 Lambda 函数设置。例如,如果您想停止和启动多个实例,那您可能需要一个不同的超时的值,以及不同的内存

7.    选择保存

8.    重复第 1-7 步来创建另一个函数。执行以下不同的操作,从而让此函数启动您的 EC2 实例:
在第 3 步中,输入函数名,将其作为用于启动 EC2 实例的函数。例如“StartEC2Instances”。
在第 5 步中,复制以下代码并粘贴到代码编辑器的编辑器窗格 (lambda_function) 中:

注意:对于区域实例,使用与停止 EC2 实例的代码相同的值。

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']

def lambda_handler(event, context):
    ec2 = boto3.client('ec2', region_name=region)
    ec2.start_instances(InstanceIds=instances)
    print 'started your instances: ' + str(instances)

测试 Lambda 函数

1.    在 Lambda 控制台中,选择函数

2.    选择您创建的一个函数。

3.    选择操作,然后选择测试

4.    在配置测试事件对话框中,选择创建新测试事件

5.    输入事件名称,然后选择创建

注意:您不需要更改测试事件的 JSON 代码 — 该函数不使用此信息。

6.    选择测试以执行此函数。

7.    为您创建的其他函数重复第 1-6 步。

提示:您可以在测试之前和测试之后检查您的 EC2 实例的状态,从而确认您的函数运行符合预期。

创建触发 Lambda 函数的规则

1.    打开 CloudWatch 控制台

2.    在左侧导航窗格的事件下,选择规则

3.    选择创建规则

4.    在事件源下,选择计划

5.    执行以下任意一项操作:
对于固定频率为,输入间隔时间(分钟数、小时数或天数)。
对于 Cron 表达式,输入指示 Lambda 何时停止实例的表达式。有关规则语法的详细信息,请参阅规则的计划表达式
注意:Cron 表达式使用 UTC 进行计算。务必针对您的首选时区调整表达式。

6.    在目标下,选择 Add target(添加目标)

7.    选择 Lambda 函数

8.    对于函数,选择将停止 EC2 实例的函数。

9.    选择配置详细信息

10.    在规则定义下,执行以下操作:
对于名称,输入识别规则的名称,例如“StopEC2Instances”。
(可选)对于描述,输入对规则的描述。例如“每天晚上 10 点停止 EC2 实例”。
对于状态,选中已启用复选框。

11.    选择创建规则

12.    重复第 1-11 步来创建规则以启动您的 EC2 实例。以不同的方式执行以下操作:
在第 5 步中,对于 Cron 表达式,输入指示 Lambda 何时启动实例的表达式。
在第 8 步中,对于函数,选择将启动您的 EC2 实例的函数。
在第 10 步中,在规则定义下,输入一个名称(如“StartEC2Instances”),也可以选择输入描述(如“每天早晨 6 点启动 EC2 实例”)。