如何在预定时间停止并重新启动测试或非关键 AWS Elastic Beanstalk 环境?

上次更新日期:2022 年 7 月 12 日

我想在预定的时间终止并重建我的测试或非关键 AWS Elastic Beanstalk 环境。

简短描述

您可以使用 API 调用 terminate-environmentrebuild-environment 来停止并重新启动 Elastic Beanstalk 环境。您只能在环境终止后的六周(42 天)内重建已终止的环境。

要按计划执行这些调用,请在 Amazon CloudWatch Events 中配置事件,以便在每天的特定时间触发 AWS Lambda 函数。然后,配置这些 Lambda 函数以进行 Elastic Beanstalk API 调用。

重要提示:在终止环境后,您对 Elastic Beanstalk 环境或其实例所做的任何带外更改都不会得到保留。在改变环境时一定要考虑这个因素。另需注意终止时间,并在此之前完成使用此实例的任何工作。即使用户并未连接到实例,该实例也将在计划的时间终止。

注意:您可以创建配置 AWS CloudFormation 模板,以执行以下解决方法中的所有操作。模板必须为 Lamdba 创建一个 AWS Identity and Access Management (IAM) 执行角色。然后,模板必须启动 Lambda 函数,停止 Lambda 函数,最后触发 CloudWatch 事件。

解决方法

在开始之前,请记下您的 Elastic Beanstalk 环境的 ID (EnvironmentId)。

重要提示:以下解决方法可以从 Elastic Beanstalk 环境和资源中删除所有服务生成的标签。

为 Lambda 函数创建 IAM 角色

1.    为 Lambda 函数的 IAM 角色创建以下内联策略(例如,Lambda.json)。例如:

$ cat Lambda.json 
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com"
        ]
      },
      "Action": [
        "sts:AssumeRole"
      ]
    }
  ]
}

2.    使用您在第 1 步中创建的策略创建 IAM 角色。例如:

aws iam create-role --role-name elasticbeanstalk-lambda-role --assume-role-policy-document file://Lambda.json

3.    记下 IAM 角色的 Amazon Resource Name (ARN)

4.    将以下托管策略附加到 IAM 角色:

aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess-AWSElasticBeanstalk --role-name elasticbeanstalk-lambda-role

创建 Lambda 函数部署程序包

1.    将以下代码复制到文本编辑器中,重新启动 Elastic Beanstalk 环境:

import boto3
envid=['e-awsenvidid']
client = boto3.client('elasticbeanstalk')
def handler(event, context):
    try:
         for appid in range(len(envid)):
             response = client.rebuild_environment(EnvironmentId=str(envid[appid].strip()))
             if response:
                 print('Restore environment %s' %str(envid[appid]))
             else:
                 print('Failed to Restore environment %s' %str(envid[appid]))

    except Exception as e:
        print(e)

重要提示:e-awsenvidid 替换为 Elastic Beanstalk 的环境 ID。前述代码示例适用于 Python 3.6 运行时。

2.    将代码另存为 Python 文件。例如:StartElasticBeanstalk.py

3.    将 Python 文件压缩为 ZIP 文件。例如:StartElasticBeanstalk.zip

4.    将以下代码复制到文本编辑器中,终止 Elastic Beanstalk 环境:

import boto3
envid=['e-awsenvidid']
client = boto3.client('elasticbeanstalk')
def handler(event, context):
    try:
         for appid in range(len(envid)):
             response = client.terminate_environment(EnvironmentId=str(envid[appid].strip()))
             if response:
                 print('Terminating environment %s' %str(envid[appid]))
             else:
                 print('Failed to Terminate environment %s' %str(envid[appid]))
             
    except Exception as e:
        print(e)

重要提示: e-awsenvidid 替换为 Elastic Beanstalk 的环境 ID。

5.    将代码另存为 Python 文件。例如:StopElasticBeanstalk.py

6.    将 Python 文件压缩为 ZIP 文件。例如,StopElasticBeanstalk.zip

创建 Lambda 函数

注意:如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请确保您使用的是最新的 AWS CLI 版本

要创建停止和重新启动 Elastic Beanstalk 环境的 Lambda 函数,请在 AWS 命令行界面 (AWS CLI) 运行以下命令:

aws lambda create-function \
--function-name StartElasticBeanstalk \
--zip-file fileb://file-path/StartElasticBeanstalk.zip \
--role arn:aws:iam::012345678912:role/elasticbeanstalk-lambda-role \
--handler StartElasticBeanstalk.handler \
--runtime python3.6 --region us-west-2

aws lambda create-function \
--function-name StopElasticBeanstalk \
--zip-file fileb://file-path/StopElasticBeanstalk.zip \
--role arn:aws:iam::012345678912:role/elasticbeanstalk-lambda-role \
--handler StopElasticBeanstalk.handler \
--runtime python3.6 --region us-west-2

重要提示:us-west-2 替换为您的 Elastic Beanstalk 环境所在的 AWS 区域。此外,请在每个命令中提供部署程序包(StartElasticBeanstalk.zipStopElasticBeanstalk.zip)和 IAM 角色的 ARN 作为参数。

创建 CloudWatch Events 规则以触发 Lambda 函数

1.    要启动和停止 Lambda 函数,请运行以下命令:

aws events put-rule --name "StartLambdaFunction" --schedule-expression "cron(0 8 * * ? *)" --region us-west-2
aws events put-rule --name "StopLambdaFunction" --schedule-expression "cron(0 18 * * ? *)" --region us-west-2

注意:--schedule-expression 属性需要使用 cron 语法。根据需要,更新 --schedule-expression 属性的值。将 us-west-2 替换为您的 Elastic Beanstalk 环境所在的 AWS 区域。

2.    要信任 CloudWatch Events 服务委托人 (events.amazonaws.com) 并将权限范围扩展为您在第 1 步中创建的规则,请运行以下命令:

aws lambda add-permission \
--function-name StartElasticBeanstalk \
--statement-id StartLambdaFunction \
--action 'lambda:InvokeFunction' \
--principal events.amazonaws.com \
--source-arn arn:aws:events:us-west-2:012345678912:rule/StartLambdaFunction --region us-west-2

aws lambda add-permission \
--function-name StopElasticBeanstalk \
--statement-id StopLambdaFunction \
--action 'lambda:InvokeFunction' \
--principal events.amazonaws.com \
--source-arn arn:aws:events:us-west-2:012345678912:rule/StopLambdaFunction --region us-west-2

注意:us-west-2 替换为您的 Elastic Beanstalk 环境所在的区域。

3.    要将您创建的 Lambda 函数添加到此规则,以便该规则按计划运行,请运行以下 put-targets 命令:

aws events put-targets --rule StartLambdaFunction --targets "Id"="1","Arn"="arn:aws:lambda:us-west-2:012345678912:function:StartElasticBeanstalk" --region us-west-2

aws events put-targets --rule StopLambdaFunction --targets "Id"="2","Arn"="arn:aws:lambda:us-west-2:012345678912:function:StopElasticBeanstalk" --region us-west-2

重要提示:将每个命令中的 ARN 替换为 IAM 角色的 ARN。将 us-west-2 替换为您的 Elastic Beanstalk 环境所在的区域。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?