知识文档


有时候在EC2上的一些业务只需要在每天的某个时间段对外提供服务,其余的时候是处于闲置空转的状态。但付费方式为EC2的按需收费,那么闲置时间产生的费用就显得浪费了。怎么办呢?通过Lambda服务结合Cloudwatch规则,实现实例的定时开关,达到节约成本的目的。

业务需求

  • 每天上午(UTC)9:00~20:00,将实例启动使其处于running状态
  • 每天晚上(UTC)20:00~次日上午9:00,将实例停止使其处于stopped状态。

环境

需要用到的AWS服务包括:

  1. EC2:即云端虚拟机,将用于运行我们的脚本。
  2. Lambda, 用于操作我们的EC2实例,即启动和关闭。
  3. IAM, AWS Identity and Access Management, 用于赋予Lambda函数操作我们EC2实例的权限。
  4. Cloud Watch, 用于定时执行我们的Lambda函数,达到定时开关机的效果。

EC2

实例的创建步骤这里就不介绍了,可以参考AWS 官方文档

测试资源如下:

Name 实例ID
XLDSMILE-US-Pordoction-app1 i-0611856bef37b1295
XLDSMILE-US-Pordoction-app2 i-01c2654a6acc2f933

创建Lambda的IAM角色

因为在创建Lambda函数时会要求选择IAM,因此这里要先把IAM角色给配置喽。

创建策略

  • 登录控制台,选择IAM服务》角色创建角色

  • 选择 创建策略 ,为角色附加自定义权限策略:

将如下JSON字符串复制到选项框内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"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": "*"
}
]
}
  • 点击 查看策略 ,为其创建名字描述,点击创建策略,跳转到以下界面。

为角色分配策略

  • 策略创建完成后返回 创建角色 界面,筛选并勾选策略

  • 点击下一步,标签啥的选默认,点击 审核创建角色

创建Lambda函数

步骤或选型:

  • 选择Lambda服务
  • 点击 函数创建函数
  • 选择“从头开始撰写”
  • 函数名称:StopEC2Instances
  • 语言:Pyhton3.8
  • 执行角色:现有角色》搜索我们刚才建立的角色
  • 点击 创建函数

将以下Python3代码复制粘贴。region替换为你的EC2 region, instancces 替换为你的instance id。这些都可以在EC2控制台找到。完成后点击 Deploy

1
2
3
4
5
6
7
8
9
# stopped your instances
import boto3
region = 'us-east-1'
instances = ['i-0571c93e69719637c', 'i-057659afa167f65a5']
ec2 = boto3.client('ec2', region_name=region)

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

这样,关闭实例的Lambda函数就创建好了,我们还需要创建一个类似的启动实例的函数

重复从 建立函数 开始的以上所有步骤,有以下几点改变:

  • 函数名称: StartEC2Instances
  • Python代码里的 ec2.stop_instances 替换为 ec2.start_instances
1
2
3
4
5
6
7
8
9
# started your instances
import boto3
region = 'us-east-1'
instances = ['i-0571c93e69719637c', 'i-057659afa167f65a5']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
ec2.start_instances(InstanceIds=instances)
print('started your instances: ' + str(instances))
  • 完成后,在Lambda控制台,就能看到我们刚才建立的两个函数


使用CloudWatch服务,创建规则

  1. CloudWatch控制台,选择规则创建规则,事件源选择计划cron表达式 ,输入 “0 9 * * ? *”
  2. 任务计划格式参考:Cron 表达式
  3. 目标选择Lambda函数,选择函数
  4. 点击配置规则详细信息,名称和描述均写StartEC2
  5. 重复步骤1操作,这时cron表达式为“0 20 * * ? *”
  6. 重复上文3,4两步骤,函数版本选择“V2”。文件名和描述均写“StopEC2”
  7. 测试,若机器到时间未停止,首先检查cron表达式和UTC时间表述。其次检查Lambda代码中的instance ID,region是否正确。