Using Lambda & CloudWatch Events to start and stop Ec2 Instances:
Use Case:
You are the admin over a large number of Ec2 instances that need to be stopped at night when they are not in use by your development team to save on costs. Your development team does not have a good habit of stopping them before they leave for work so it is your job to create an automated trigger in the AWS console to automatically conduct the action every night and/or start them every morning before the team comes in.
What Are Amazon CloudWatch Events?
Amazon CloudWatch Events delivers a near real-time stream of system events that describe changes in Amazon Web Services (AWS) resources. Using simple rules that you can quickly set up, you can match events and route them to one or more target functions or streams. CloudWatch Events becomes aware of operational changes as they occur. CloudWatch Events responds to these operational changes and takes corrective action as necessary, by sending messages to respond to the environment, activating functions, making changes, and capturing state information.
You can also use CloudWatch Events to schedule automated actions that self-trigger at certain times using cron or rate expressions.
What is AWS Lambda?
WS Lambda is a compute service that lets you run code without provisioning or managing servers. AWS Lambda runs your code only when needed and scales automatically, from a few requests per day to thousands per second. You pay only for the compute time you consume — there is no charge when your code is not running. With AWS Lambda, you can run code for virtually any type of application or backend service — all with zero administration. AWS Lambda runs your code on a high-availability compute infrastructure and performs all of the administration of the compute resources, including server and operating system maintenance, capacity provisioning and automatic scaling, code monitoring, and logging. All you need to do is supply your code in one of the languages that AWS Lambda supports.
You can use AWS Lambda to run your code in response to events, such as changes to data in an Amazon S3 bucket or an Amazon DynamoDB table; to run your code in response to HTTP requests using Amazon API Gateway, or invoke your code using API calls made using AWS SDKs. With these capabilities, you can use Lambda to easily build data processing triggers for AWS services like Amazon S3 and Amazon DynamoDB, process streaming data stored in Kinesis, or create your own back end that operates at AWS scale, performance, and security.
You can also build serverless applications composed of functions that are triggered by events and automatically deploy them using CodePipeline and CodeBuild. For more information, see AWS Lambda applications.
Let’s get started.
Log in to the AWS Console under an account with the necessary permissions. I am using one with admin privileges but not my root account.
Navigate to the IAM service and create a policy that we will attach to the Lamba service allowing it to do certain actions with certain resources (not a full access policy)
Enter in the below code in the JSON tab removing the existing default code. Then click next.
Next, we will attach this policy to a role that will be attached to the Lambda service.
Click Next.
Then Search for StartandStopInstancePolicy.
Click Next, then Next again.
Then click Create Role.
Let’s not forget to create our Ec2 Instances 😂 so that we can insert the instance id into our lambda code before creating our Lambda functions. Navigate to the Ec2 service.
We will use the very common amazon linux 2 instances.
Click Next Configure Instance Details.
We are going to create two ec2 instances and we will create a new IAM role before we leave the screen to give ec2 full access for simplicity.
On the next screen, click Create Role. Click AWS Service and Ec2 for the service. Then search for Ec2FullAccess on the next screen.
Then click next.
Then Click create role.
Prior to launching ensure that you create a new pair and download the keypair before launching the instances.
Next, locate your Ec2 instance ids that you will copy and paste into your python code on each of the startec2.py and stopeec2.py files.
Copy and paste the entire line of the file that you replace and paste it in the other .py file for simplicity.
Now we will create a Lambda Function that will invoke when we want to stop our instances to either stop or start. We will create two separate functions, one stopping and one starting the instances.
Create the startinstance function.
Start python code:
Repeat the same stop but for stop instance using the stopec2.py code for your lambda function.
Stop python code:
Now that we see we have both functions you can test the lambda function to see whether it works before you continue. You would have to run the stop instance function since we have already launched and seen that our instances are in the run state.
And it works! Let’s now trigger our corn expression (chronological event in CloudWatch).
Next, navigate to the CloudWatch service and go to events. Here we will create an event cron expression and add a custom rule to start our instances at a certain time. We will then do another one to stop it 10 minutes later.
Both rules are created.
Let’s check the final step to see if both of our instances have been stopped.
It worked 😬
Unless you are using this in a production environment, I would suggest that you terminate your ec2 instances, the lambda functions, IAM roles, and the CloudWatch event rules.