How do I stop and restart my test or non-critical AWS Elastic Beanstalk environment at a scheduled time?

5 minute read
0

I want to terminate and rebuild my test or non-critical AWS Elastic Beanstalk environment at a scheduled time.

Short description

You can stop and restart your Elastic Beanstalk environment with the API calls terminate-environment and rebuild-environment. You can rebuild terminated environments only within six weeks (42 days) of their termination.

To perform these calls on a schedule, configure events in Amazon CloudWatch Events to start AWS Lambda functions at a specific time each day. Then, configure those Lambda functions to make the Elastic Beanstalk API calls.

Important: Any out-of-band changes that you make to an Elastic Beanstalk environment or its instances don't persist after you terminate the environment. Note the termination time and complete any work that uses the instance before that time. The instance terminates at the scheduled time, even if a user isn't connected to that instance.

You can create and configure an AWS CloudFormation template to perform all the actions in the following resolution. The template must create an AWS Identity and Access Management (IAM) role for Lambda. Then, the template must start the Lambda function, stop the Lambda function, and finally initiate the CloudWatch event.

Resolution

Prerequisite

Note your Elastic Beanstalk environment's ID (EnvironmentId).

Important: The following resolution can remove all service-generated tags from your Elastic Beanstalk environment and resources.

Create an IAM role for your Lambda function

1.    Create the following inline policy (for example, Lambda.json) for an IAM role for your Lambda function:

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

2.    Use the policy to create an IAM role:

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

3.    Note the IAM role's Amazon Resource Name (ARN).

4.    Attach the following managed policy to the IAM role:

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

Create a Lambda function deployment package

1.    To restart the Elastic Beanstalk environment, paste the following code into a text editor:

import boto3envid=['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)

Important: Replace e-awsenvidid with your environment ID for Elastic Beanstalk. The preceding code example is compliant with Python 3.9 runtimes.

2.    Save the code as a Python file. For example: StartElasticBeanstalk.py

3.    Compress the Python file as a ZIP file. For example: StartElasticBeanstalk.zip

4.    To terminate the Elastic Beanstalk environment, paste the following code into a text editor:

import boto3envid=['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)

Important: Replace e-awsenvidid with your environment ID for Elastic Beanstalk.

5.    Save the code as a Python file. For example: StopElasticBeanstalk.py

6.    Compress the Python file as a ZIP file. For example: StopElasticBeanstalk.zip

Create your Lambda function

Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshoot AWS CLI errors. Also, make sure that you're using the most recent AWS CLI version.

To create Lambda functions that stop and restart your Elastic Beanstalk environment, run the following commands in the 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.9 --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.9 --region us-west-2

Important: Replace us-west-2 with the AWS Region where your Elastic Beanstalk environment is located. Also, provide the deployment package (StartElasticBeanstalk.zip or StopElasticBeanstalk.zip) and IAM role's ARN as parameters in each command.

Create a CloudWatch Events rule to initiate the Lambda function

1.    To start and stop the Lambda function, run the following commands:

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

Note: The --schedule-expression property requires cron syntax. Update the values for the --schedule-expression property as needed. Replace us-west-2 with the AWS Region where your Elastic Beanstalk environment is located.

2.    To trust the CloudWatch Events service principal (events.amazonaws.com) and extend the scope of the permissions to the rules, run the following commands:

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

Note: Replace us-west-2 with the AWS Region where your Elastic Beanstalk environment is located.

3.    To add the Lambda function that you created to this rule so that the rule runs on schedule, run the following put-targets command:

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

Important: Replace the ARN in each command with the IAM role's ARN. Replace us-west-2 with the AWS Region where your Elastic Beanstalk environment is located.

Related information

Elastic Beanstalk template snippets

Lambda deployment packages

AWS OFFICIAL
AWS OFFICIALUpdated a year ago