有没有一种简单的方法可以在每天的给定时间启动和停止 AWS EC2 实例?这可以为我的开发和测试服务器节省很多钱。
答案1
更新
AWS 发布了一款名为“实例调度程序“,包括完整的配置指南该页面有链接。它看起来是我下面描述的 EC2 Scheduler 的增强版,具有更多功能,但本质上是相同的。
下面的指南仍然有效,但最好查看新安装的实例调度程序。
原始帖子
AWS 有一个工具叫EC2 调度程序这使您可以非常灵活地控制启动和停止 EC2 实例。
该工具允许您在设置工具时定义默认的开始和停止时间,稍后您可以更改这些时间。您可以选择控制哪些实例,也可以使用标签为每个实例指定不同的开始和停止时间。
虽然这是一款很棒的工具,但文档有些模糊和混乱。文档好像是由一位编写了该工具并了解一切的工程师编写的,而不是由一位技术作家编写的。
笔记:如果您有反馈或更正意见,欢迎提出。如果您对此有疑问,请提出您自己的问题。
什么是 EC2 Scheduler
此工具是一个可与 Cloudwatch Events 和 DynamoDB 配合使用的 Lambda 函数。它使用 Cloudformation 模板进行部署,该模板还设置了必要的 IAM 角色和策略。您可以阅读有关架构的信息这里。
部署
首先这一页并点击“启动解决方案”。现在的直接链接是这里,但它可能会改变。
在控制台顶部选择要部署资源的区域。该脚本可控制任何区域中的 EC2 实例,但它在一个区域中运行。
标记 EC2 实例
文档中介绍了这一点这里,但事情并没有想象的那么简单。
您可以通过标记实例来控制启动和停止哪些实例。
最简单的情况是,您需要标记要按计划启动和停止的每个 EC2 实例。为此,请在控制台中找到您的 EC2 实例,单击标签,然后创建此标签
要启用复制和粘贴:
- 密钥:scheduler:ec2-startstop
- 值: true
如果您希望按照不同的时间表启动和停止特定实例,请将其他信息附加到标签键和值。例如,如果您希望实例在星期二、星期四和星期五的 15:00 UTC 启动并在 24:00 UTC 停止,请输入以下内容。
键:scheduler:ec2-startstop:late 值:1500;2400;utc;tue,thu,fri
注意,“late”这个词可以是任何字符串,“late”没有特殊含义。
您可以使用以下方式将 UTC 转换为本地时间此工具。
您可以使用标签编辑器批量标记实例。这样可以更轻松地设置批量标记,这对于为开发、测试和生产设置不同的设置非常有用。不过,我怀疑您是否会在生产中使用它。
CloudFormation 参数
运行 CloudFormation 模板时,您必须输入许多参数。大多数参数可以保留默认值。以下是一些最重要的参数
- 堆栈名称:您可以随意命名。它就是在 CloudFormation 中的名称。
- 自定义标签名称:这是您针对 EC2 实例放置的标签的“键”。除非您有充分的理由,或者需要多次安装,否则请保留默认值。
- 默认启动/停止时间:启动和停止实例的默认 UTC 时间
- DynamoDB:设置存储在 DynamoDB 中。您可以更改表名等。由于 DynamoDB 免费套餐不会过期,因此大多数人不太可能被收费。
- (第二个屏幕)权限 - 这是个误导,请参阅下面的部分。保留其默认值,并在尝试设置 EC2 调度程序时以管理员身份运行。
- 通知选项:我发现设置 SNS 通知很有用,这样我就可以验证它是否正常工作。我还没有花时间研究如何禁用它们,我只是删除了它,重新运行 Cloudformation 模板来重新安装。
权限、策略和角色
CloudFormation 模板的权限/IAM 角色部分是转移注意力的借口 - 也就是说,它基本上无关紧要。它仅指定用于运行 CloudFormation 脚本的角色,它对创建的资源或 lambda 函数运行时使用的角色没有影响。回想起来,这是显而易见的,但我刚开始时并不明显。
无论你以何种角色运行此脚本,都会在 IAM 中创建相同的角色和内联权限。Lambda 函数使用脚本创建的“ec2 调度程序角色”运行。
我在下面列出了我的政策,希望它们对任何人都有帮助。
CloudWatch 事件和指标
如果您想查看 Lambda 函数的日志,请进入 Cloudwatch Events。日志记录非常好。还有指标,因此您可以查看它的运行时间、运行时间等。
额外的
lambda 函数的代码可以在Github。
政策
这些通常不是必需的,但对某些人来说可能是必要的,所以我会将它们包括在内。
IAM 角色策略
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeTags",
"iam:CreateRole",
"iam:GetRole",
"iam:PassRole",
"iam:PutRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"dynamodb:*",
"lambda:*",
"SNS:Publish",
"events:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "S3:GetObject",
"Resource": [
"arn:aws:s3:::solutions-us-west-2",
"arn:aws:s3:::solutions-us-west-2/*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:StopInstances",
"ec2:StartInstances"
],
"Resource": [
"arn:aws:ec2:us-west-2:123456789012:instance/i-0d112345Ab6789012"
]
}
]
}
IAM 角色的信任策略
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com",
"cloudformation.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
答案2
如果您只想启动和停止实例,这里有另一种方法,它也利用了 Lambda 服务。它假设您想要控制特定的实例 ID。您可以通过添加更多以逗号分隔的 ID 来控制多个实例。(例如:“i-3453453”,“i-45656745”)。您可以在 AWS 控制台实例部分中找到实例的 ID。
在 Lambda 控制台中
- 打开 AWS Lambda 控制台,然后选择创建函数。
- 选择从头开始创作。
- 输入您的函数的名称,例如“StopEC2Instances”。
- 对于运行时,选择 Python 2.7
- 展开角色下拉菜单,然后选择创建自定义角色。这将在浏览器中打开一个新选项卡或窗口。
- 在 IAM 角色下拉菜单中,选择创建一个新的 IAM 角色,然后输入角色名称,例如“lambda_start_stop_ec2”。
- 选择查看策略文档、编辑,然后在提示阅读文档时选择确定。将策略中的所有文本替换为以下内容:
下面的代码
{
"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": "*"
}
]
}
- 选择允许以完成角色创建并返回 AWS Lambda 控制台。
- 要停止实例,请将函数代码编辑器中的所有文本替换为以下内容:
下面的代码
import boto3
region = ' eu-west-1'
instances = ['i-0dd344443184503fa']
def lambda_handler(event, context):
ec2 = boto3.client('ec2', region_name=region)
ec2.stop_instances(InstanceIds=instances)
print 'stopped your instances: ' + str(instances)
请记住用您自己的值替换区域和实例值。
- 从运行时下拉菜单中,选择 Python2.7。
- 在基本设置中,为超时功能输入 10 秒。
- 选择保存。
- 重复所有步骤来创建另一个将启动实例的函数,然后使用这个 Python 脚本来启动它:
下面的代码
import boto3
region = 'eu-west-1'
instances = [' i-0dd344443184503fa']
def lambda_handler(event, context):
ec2 = boto3.client('ec2', region_name=region)
ec2.start_instances(InstanceIds=instances)
print 'started your instances: ' + str(instances)
安排职能
在这里,您将创建一个 CloudWatch 事件,它将在晚上触发您的 Lambda 函数
- 打开 Amazon CloudWatch 控制台。
- 选择事件,然后选择创建规则。
- 在事件源下选择计划。
- 输入时间间隔或 cron 表达式,告知 Lambda 何时停止实例。有关正确语法的更多信息,请参阅规则的计划表达式语法。
注意:Cron 表达式以 UTC 为单位进行评估。请务必根据您首选的时区调整表达式。以下是每天 08:00 GMT/UTC 运行该函数的示例):
0 08 * * ? *
- 选择添加目标,然后选择 Lambda 函数。
- 对于函数,选择停止实例的 Lambda 函数。
- 选择配置详细信息。
- 在提供的字段中输入以下信息:对于名称,请输入一个有意义的名称,例如“StopEC2Instances”。对于描述,请添加一个有意义的描述,例如“每天晚上停止 EC2 实例”。对于状态,请选择已启用。
- 选择创建规则。
要在早上重启实例,请重复这些步骤并使用您喜欢的开始时间。如果您想在函数失败时发送邮件消息,您可以设置 SNS 主题并在 Lmbda 函数创建窗口的调试下配置该消息的发送。
所有这些的来源可以在这里找到:AWS 文档
答案3
实现相同目标的更简单方法是使用 AWS EventBridge 规则。
转到 Amazon EventBridge > 规则
创建新规则并选择规则类型作为日程。
提供 cron 表达式用于实例关机计划。例如 cron(30 17 * * ? *)
为了目标1, 选择:
- 目标类型作为“AWS 服务”
- 目标作为“AWS StopInstances API 调用”, 和
- 提供实例 ID按计划关闭。
- 最后,选择为该特定资源创建新角色
检查计划和实例详细信息并完成创建规则。
您可以使用上面提到的方法(使用 lambda)再次启动同一个实例。