How do I stop and restart my Elastic Beanstalk environment on a schedule?

Last updated: 2019-11-8

How can I 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 only rebuild terminated environments within six weeks (42 days) of their termination.

To perform these calls on a schedule, configure events in Amazon CloudWatch Events to trigger 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 the environment is terminated. Be sure to consider this factor when changing your environment. Also, note the termination time, and complete any work that's using the instance before that time. The instance terminates at the scheduled time even if a user isn't connected to that instance.

Resolution

Before proceeding, make sure to 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 AWS Identity and Access Management (IAM) role for your Lambda function. See the following example:

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

2.    Create the IAM role using the policy that you created in step 1, as follows:

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/AWSElasticBeanstalkFullAccess --role-name elasticbeanstalk-lambda-role

Create a Lambda function deployment package

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

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)

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

Note: The preceding code example is compliant with Python 3.6 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, copy the following code into a text editor:

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)

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

To create Lambda functions that stop and restart your Elastic Beanstalk environment, run the following commands in the AWS Command Line Interface (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

Important: For this step and others, be sure to replace us-west-2 with the 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 trigger 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-2
aws events put-rule --name "StopLambdaFunction" --schedule-expression "cron(0 18 * * ? *)" --region us-west-2

Note: The --schedule-expression property requires cron syntax. Be sure to update the values for this property as needed.

2.    To trust the CloudWatch Events service principal (events.amazonaws.com) and to extend the scope of the permissions to the rules that you created in step 1, run the following add-permission 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

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.

Use AWS CloudFormation templates

You can create an AWS CloudFormation template to perform all the actions in this resolution. You can configure the template to create the Lambda IAM execution role, start the Lambda function, stop the Lambda function, and then trigger the CloudWatch event.


Did this article help you?

Anything we could improve?


Need more help?