Managing Amazon EC2 Instances using Amazon SES

Background

Most people know Amazon Simple Email Service (SES) just as a service for sending out emails. However, did you know that you can use it to receive emails as well? If this interests you, more information is available at https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email.html.

In this blog I will show how I provisioned a solution to manage my Amazon EC2 instances using emails. The solution uses Amazon SES and AWS Lambda. Now, some of you might be saying, can’t you just use the AWS console or app for this? Well, yes you can, however for me personally, logging into an AWS console just to get the status of my Amazon EC2 instances, or to start/stop them was more effort than I deemed necessary. The app surely makes this task trivial, however the main purpose of this blog is to showcase the capabilities of Amazon SES

Solution Architecture

Below is the high-level design for my solution.

The individual steps (labelled using numbers) are described below

  1. The admin sends an email to an address attached to an Amazon SES rule
  2. Amazon SES receives the email, performs a spam and virus check. If the email passes the check, Amazon SES invokes the manageInstances AWS Lambda function, passing the contents of the email to it (unfortunately the contents of the body are not passed)
  3. The manageInstances AWS Lambda function authenticates the sender based on the from address (this is a very rudimentary authentication system. A stronger authentication mechanism must be used if this solution is to be deployed in a production environment – maybe include a multi-factor authentication system). It extracts the command from the email’s subject and executes it
  4. The manageInstances AWS Lambda function uses Amazon SES to send the response of the command back to the admin
  5. Amazon SES delivers the email containing the command’s output to the admin

Prerequisites

To use Amazon SES for receiving incoming emails, first verify your domain within it and then point your domain’s DNS MX entry to your region’s Amazon SES endpoint. Full Instructions to carry this out can be found at https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-getting-started.html

Implementation

Lambda Function

The Lambda function is created first as it is required for the Amazon SES Rules.

The Lambda function carries out the following tasks

  • authenticates the sender by comparing the email’s from address with a predefined list of approved senders. To prevent a situation where the Lambda function can be inadvertently used as a spam bot, all emails from senders not on the approved list will be dropped.
  • checks if the specified command is in the list of commands that is currently supported. If yes, then the command is executed, and the output sent back to the admin. If the command is unsupported, a reply stating that an invalid command was specified is sent back to the admin

Here are the attributes of the Lambda function I created

Function name: manageInstances
Runtime:             Python 3.6
Region:                North Virginia (us-east-1) This is to ensure that the Lambda function and the Amazon SES rules are in the same region
Role:                     The role that is used by the Lambda function must have the following permissions attached to it

             ec2:DescribeInstances
             ec2:StartInstances
             ec2:StopInstances
             SES:SendEmail

Here is the code for the AWS Lambda function (set the approvedSenders list to contain the email address of approved senders)

The AWS Lambda function code can be downloaded from https://gist.github.com/nivleshc/f9b32a14d9e662701c3abcbb8f264306

Amazon SES Email Receiving Rule

Next, the Amazon SES Email Receiving rule that handles the incoming emails must be created. Please note that currently Amazon SES is supported in a few regions only. For my solution, I used the North Virginia (us-east-1) region.

Below are the steps to create the rule

  • Open Simple Email Service service page from within the AWS console (ensure you are in the correct AWS region)
  • From the left-hand side menu, navigate down to the Email Receiving section and then click Rule Sets.
  • The right-hand side of the screen will show the currently defined rule sets. I used the predefined default-rule-set.
  • Click on View Active Rule Set and then in the next screen click Create Rule.
  • In the next screen, for the recipient address, enter the email address to which emails will be sent to, to carry out the commands (the email domain has to correspond to the domain that was verified with Amazon SES, as part of the prerequisites mentioned above)
  • In the next screen, for actions, select Lambda.
  • Select the name of the Lambda function that was created to manage the instances from the drop down (for me, this was manageInstances)
  • Ensure the Invocation type is set to Event.
  • You do not need to set the SNS topic, however if you need to know when this Amazon SES action is carried out, select the appropriate SNS topic (you will need to create an SNS topic and subscribe to it using your email address)
  • Click Next Step.
  • In the next screen, provide a name for the rule. Ensure the options Enabled and Enable spam and virus scanning are ticked.
  • Click Next Step and then review the settings.
  • Click Create Rule.

Usage

The solution, once implemented supports the following commands

help   - provides information about the commands and their syntax
status - provides the status of all Amazon EC2 instances in the region that the Lambda function is running in. It lists the instance-id and name of those instances (name is derived from the tag with the key Name)
start {instance-id} - starts the Amazon EC2 instance that has the specified instance-id
stop {instance-id}  - stops the Amazon EC2 instance that has the specified instance-id

To use, send an email from an approved sender’s email to the email address attached to Amazon SES.

The table below shows, what the subject must be, for each command.

Command Subject
Help help
Status for instances in us-east-1 status
Start an instance with instance-id i-0e7e011b42e814465 start i-0e7e011b42e814465
Stop an instance with instance-id i-0e7e011b42e814465 stop i-0e7e011b42e814465

The output of the status command is in the following format

<instance-id> <instance-name> <status> <private-ip> <public-ip>

for example
i-03a1ab124f554z805 LinuxServer01 Running 172.16.31.10 52.10.100.34

The only problem with the solution is that all commands are performed on Amazon EC2 instances running in the same AWS region as the Lambda function. What if you wanted to carry out the commands on another region?

For the keen eyed, you would have spotted the Easter egg I hid in the Lambda function code. Here is what the subject must be if the command is to be carried out in an AWS region different to where the Lambda function is running (simply provide the AWS region at the end of the command)

Command Subject
Help help
Status for instances in ap-southeast-2 (Sydney) status ap-southeast-2
Start an instance with instance-id i-0e7e011b42e814465 in ap-southeast-2 (Sydney) region start i-0e7e011b42e814465 ap-southeast-2
Stop an instance with instance-id i-0e7e011b42e814465 in ap-southeast-2 (Sydney) region stop i-0e7e011b42e814465 ap-southeast-2

There you go! Now you can keep an eye on and control your Amazon EC2 instances with just your email.

A good use case can be when you are commuting and need to RDP into your Windows Amazon EC2 instance from your mobile (I am guilty of doing this at times). You can quickly start the Amazon EC2 instance, get its public ip address, and then connect using RDP.  Once finished, you can shut down the instance to ensure you don’t get charged after that.

I hope this blog was useful to you. Till the next time, Enjoy!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.