Skip to content

Instantly share code, notes, and snippets.

@FANMixco
Forked from veuncent/toggleAutoScalingGroup.md
Last active February 7, 2024 09:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save FANMixco/8ee7f9a0ca90532eb8b52c86932594b4 to your computer and use it in GitHub Desktop.
Save FANMixco/8ee7f9a0ca90532eb8b52c86932594b4 to your computer and use it in GitHub Desktop.
AWS Auto Scaling Groups: scheduled start/stop

Many times, we have a lot of cloud waste because we never shut down our services/EC2 instances. One of the trickiest cases to control is the Auto Scaling Groups.

Now, this tutorial that is based on Vicent's one, I'm going to help you automate this task using AWS EventBridge and Lambda functions.

It's important to highlight that you must create two Lambda functions:

  1. One for stopping that is going to have a 0 as the environment variables (MAX_SIZE and DESIRED_CAPACITY).
  2. One for starting that is going to have 1+ as the environment variables (MAX_SIZE and DESIRED_CAPACITY).

Now, the steps:

Create new Lambda function and Start Event

  1. Open AWS Lambda in the console and click Create a Lambda function.
  2. Choose Author from Scratch.
  3. Give a name like ScheduleASStart.
  4. For Runtime, select Python 3.9.
  5. Click on Add Trigger.
  6. Choose EventBridge (CloudWatch Events).
  7. Click on Create a new rule.
  8. Enter a Rule name and Rule description.
  9. For Rule type, select Schedule expression.
  10. For Schedule expression, enter a Cron expression to specify at which day(s) and time this event should trigger.
    For now, only specify the event to start servers (E.g., at the beginning of the weekday). We will configure the second event later in this tutorial.
    E.g., cron(00 06 ? * MON-FRI *) fires every weekday (Monday to Friday) at 6:00 AM UTC. See this website for a handy Cron calculator.
  11. Click on Add.

Configure function

  1. On the Configure function page, enter a Name and Description for the function.

  2. For Code entry type make sure Edit code inline is selected.

  3. Delete the existing code and paste the following code into the code field:

    import os
    import boto3
    
    client = boto3.client('autoscaling')
    
    def get_env_variable(var_name):
    	msg = "Set the %s environment variable"
    	try:
    		return os.environ[var_name]
    	except KeyError:
    		error_msg = msg % var_name
    
    def lambda_handler(event, context):
    	auto_scaling_groups = get_env_variable('NAMES').split()
    
    	for group in auto_scaling_groups:
    		if servers_need_to_be_started(group):
    			action = "Starting"
    			min_size = int(get_env_variable('MIN_SIZE'))
    			max_size = int(get_env_variable('MAX_SIZE'))
    			desired_capacity = int(get_env_variable('DESIRED_CAPACITY'))
    		else:
    			action = "Stopping"
    			min_size = 0
    			max_size = 0
    			desired_capacity = 0
    
    		print (action + ": " + group)
    		response = client.update_auto_scaling_group(
    			AutoScalingGroupName=group,
    			MinSize=min_size,
    			MaxSize=max_size,
    			DesiredCapacity=desired_capacity,
    		)
    
    		print (response)
    
    def servers_need_to_be_started(group_name):
    	min_group_size = get_current_min_group_size(group_name)
    	if min_group_size == 0:
    		return True
    	else:
    		return False
    	
    
    def get_current_min_group_size(group_name):
    	response = client.describe_auto_scaling_groups(
    		AutoScalingGroupNames=[ group_name ],
    	)
    	return response["AutoScalingGroups"][0]["MinSize"]
    
  4. For Environment variables add the following:

  • NAMES - Space separated list of the Auto Scaling Groups you want to manage with this function
  • MIN_SIZE - Minimum size of the Auto Scaling Group(s) when EC2 instances are started. e.g., 0
  • MAX_SIZE - Maximum size of the Auto Scaling Group(s) when EC2 instances are started. e.g., 1
  • DESIRED_CAPACITY - Desired capacity of the Auto Scaling Group(s) when EC2 instances are started. e.g., 1
  1. For Handler, make sure the value is lambda_function.lambda_handler.

  2. For Role, select Create a custom role. An IAM wizard will open a new tab.

  3. For IAM Role, select Create a new IAM Role.

  4. Enter a Role Name.

  5. Click on View Policy Document and click Edit.

  6. A warning popup will appear. Click Ok.

  7. Add the following statement right after the closing } of "Resource": "arn:aws:logs:*:*:*" }

    ,
    {
    	  "Effect": "Allow",
    	  "Action": "autoscaling:*",
    	  "Resource": "*"
    	}
    
  8. Click on Allow.

  9. Back on the Configure function screen, make sure your new Role is selected under Existing role.

  10. Click on Next and Create Function.

Create Stop Event

  1. Create a new function like the first section.
  2. Configure the Environment variables:
  • NAMES - Space separated list of the Auto Scaling Groups you want to manage with this function
  • MIN_SIZE - Minimum size of the Auto Scaling Group(s) when EC2 instances are started. e.g., 0
  • MAX_SIZE - Maximum size of the Auto Scaling Group(s) when EC2 instances are started. e.g., 0
  • DESIRED_CAPACITY - Desired capacity of the Auto Scaling Group(s) when EC2 instances are started. e.g., 0
  1. Click on Add Trigger.
  2. Choose EventBridge (CloudWatch Events).
  3. Click on Create a new rule.
  4. Enter a Rule name and Rule description.
  5. For Rule type, select Schedule expression.
  6. For Schedule expression, enter a Cron expression to specify at which day(s) and time this event should trigger.
    E.g., cron(00 20 ? * MON-FRI *) fires every weekday (Monday to Friday) at 20:00 PM UTC. See this website for a handy Cron calculator.
  7. Click on Add.

That's it, all done!
You can test the function by hitting the Test button. The first time an Input test event popup will appear.
For the Sample event template select Scheduled event and click Save and test.

Acknowledgement

This tutorial on Nick Todd's blog helped me setting up this tutorial.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment