Stop your Amazon EC2 instances via AWS Lambda and receive an email notification via Amazon SNS or a message on Slack

Angelo Malatacca
6 min readOct 31, 2022

--

Another day is over, you are lying comfortably in your bed, you have checked that the door of the house is closed, the windows are closed and you have turned off the light. But have you terminated/stopped your EC2 instances used during the day for testing?
You forgot, right?
Now you have to get up, turn on your pc, connect to the console or use CLI. But don’t worry, from now on, a Lambda function will do it for you and you can sit comfortably in bed and receive a message or notification about the outcome.
In this tutorial we will see how to create a Lambda function that checks in each AWS region if there are EC2 instances that do not contain a specific tag, terminates/stops them and sends a notification using Amazon SNS. We will also see how to receive the same notification on a Slack channel also using a Lambda function.

Creating the Lambda function

Let’s start by creating the Lambda function that will check the active instances in each region. Let’s open the AWS console, select Lambda and Create a new function, select the “Author from scratch” option, give a name to the function, as Runtime choose Python 3.9 and leave the rest by default, we will think about changing the necessary permissions later to the function to perform all operations.

Paste the following code and click on “Deploy

In this case the function will stop all instances that do not have the “dontstop” tag set as “true”. In the instances that we want to be left running by the function we will add a tag that has as Key “dontstop” and as Value “true”. The above function stops the instances but if you prefer to terminate them just replace the instance.stop() command with instance.terminate().
The topic_arn variable is empty at the moment but we will go to paste the ARN of the SNS topic as soon as we have created it.
The function takes a few seconds to run, so the default Lambda timeout of 3 seconds is not enough. To change it, go to “Configuration” then to “General configuration”, edit and insert the new timeout. In my case 30 seconds are enough.

Let’s now change the permissions of the function. Also from the “Configuration” menu, select “Permission” and click on the name of the role that was created automatically when we created the function.

On this page, we will see that a basic function with permissions to make the Lambda function work has already been created, but we need to add additional permissions to be able to interact with the instances and send messages via SNS. We will then click on “Add permissions” and select “Create inline policy” from the drop-down menu.

Here we select the JSON option and paste the following code relating to the interaction with EC2 instances:

Click on “Review policy”, give a name and select “Create Policy”.
Repeat the same operation for the policy regarding the interaction with SNS and this time insert the following code:

Amazon SNS topic

At this point the function is ready, now we need to create a Topic SNS to be able to send the email. Select Simple Notification Service from the AWS console, select “Topics” from the menu on the left and finally “Create topic”.
As “Type” select Standard, give a name to the topic and leave the rest by default, scroll to the end of the page and click on “Create topic”.
Once the topic has been created, we must add a subscription to it, to do this, select the newly created topic and under “Subscriptions” select “Create subscription”.

Select “Email” as Protocol, enter the email on which you would like to receive notifications as “Endpoint” and click on “Create subscription”.
At this point you will receive an email containing a link on which you will click to confirm the subscription to the topic.
Once the topic has been created, copy the ARN and paste it into the Lambda function in the topic_arn variable (don’t forget the single quotes).

Amazon EventBridge rule

The Lambda function has been created, the SNS topic too, now all that remains is to automate the execution of the function itself. To do this we will use Amazon EventBridge. Select the service from the console and click on “Rules” in the menu on the left under the heading “Events”. Let’s click on “Create rule”. Give the rule a name and, if we want, a description, select “Schedule”, leave the rest of default and go on clicking on next. Insert the necessary data in the cron expression, in my case 0 21 ? * MON-FRI *, as I want the function to be invoked every day from Monday to Friday at 22:00 GMT + 1.

Let’s go to the next page and select “AWS service” as Target types. As target select “Lambda function” from the drop-down menu and as “Function” choose the function created previously and continue until the creation of the rule.

Congratulations, from now on you will not have to get out of bed if you have forgotten one or more instances that you no longer need running, Lambda will stop/terminate them for you.
But remember to tag the instances you want to remain running.

Slack channel Bonus

In addition to receiving an email, it is also possible to receive the message on Slack. To do this, you need to create an app in your Slack workspace. Navigate to https://api.slack.com/, select “Create an app”, select “From scratch”, give the app a name and choose the workspace where you want to create it. Make sure you have the necessary creation permissions. In the “Add features and functionality” menu choose “Incoming Webhooks”.

Activate the option and choose “Add New Webhook to Workspace”. In the next screen choose the channel or the contact you want the app to send the message (the channel must have been created previously) and click on “Allow”. In the Webhooks page we will now see a link called “Webhook URL”, let’s keep it aside because we will need it shortly.

Let’s open the AWS console and let’s create a new Lambda function (for the various steps, refer to what was written previously). Paste the following code and click on “Deploy”.

We pass the Webhook URL as a variable to the function, without having to hardcode it. To do this, go to the function configuration menu and on the left choose Environment variables, click on Edit and insert “SLACK_URL” as Key and the Webhook URL as Value.

Now we need to add a trigger to the function. To do this, always from the configuration menu select “Triggers” and then “Add trigger”. On the next page choose SNS from the drop-down menu and the previously created topic.

From this moment on, you will receive the same message regarding the stop or termination of the untagged instance also on Slack.

--

--

Angelo Malatacca
Angelo Malatacca

Written by Angelo Malatacca

AWS Solutions Architect certified | ex AWS Community Builder | IT lover and addicted

Responses (2)