Display Control Plane API Operations using Amazon CloudWatch Logs Insights

Introduction

For small organisations that cannot afford to spend much on their network security, moving to the cloud enables them to easily uplift their security posture. The organisation can concentrate on innovating and scaling their workloads, while AWS provides them with a secure environment to use. More information regarding AWS security and compliance can be found at https://docs.aws.amazon.com/whitepapers/latest/aws-overview/security-and-compliance.html

The sentence above is not entirely accurate. The security of workloads in AWS is a shared responsibility between AWS and the customer. AWS is responsible for “Security of the cloud”. This means that AWS is responsible for protecting the infrastructure that runs the workloads (hardware, software, networking, physical facilities). The customer is responsible for “Security in the cloud”. This means that the customer, based on the service they select, must perform all the necessary security configuration and management tasks to keep the workload secure. A good place to learn more about this is at https://aws.amazon.com/compliance/shared-responsibility-model/

As a good security practice, one must always monitor all the activities that happen in their cloud environment, especially those that involve the management of resources. For instance, if one notices a lot of large Amazon EC2 instances being provisioned, this could possibly be an indication of a breach (or someone authorised is provisioning these without notifying others). The management operations performed on resources in your AWS account are referred to as Control Plane operations.

There are many commercial products that can help you with monitoring your AWS environment. However, you can quite adequately benefit from the tools that are natively provided by AWS as well.

In this blog, I will take you through the steps of using Amazon CloudWatch Logs Insights, to easily display the Control Plane operations, in a meaningful way.

Implementation

Let’s start:

  1. Open the AWS Console and then navigate to the AWS CloudTrail service page. Change to the appropriate AWS region.
  2. Create a new Trail to record just Management events. Ensure it is applied to all the regions and that it delivers events to Amazon CloudWatch Logs as well. Below is a screenshot of the required settings

  3. Open the Amazon CloudWatch service page and ensure it is in the same region as the AWS CloudTrail that was just configured (in step 2 above)
  4. Click on Dashboards and then click on Create dashboard. Give the dashboard a meaningful name (I called my dashboard ControlPlaneOperations-Dashboard)
  5. In the next screen, from the top menu, click on Add widget. Another screen will open. Select Query results and then click on Configure

  6. In the next screen, use the drop-down arrow (pointed by the red arrow below) to select the CloudWatch Log group that was configured for the new CloudTrail in step 1 above.

    In the formula section (denoted by the red rectangle), delete everything and replace it with the text below (the screenshot above already has the correct formula)

    fields eventTime, userIdentity.userName, userIdentity.accessKeyId, sourceIPAddress, awsRegion, eventSource, eventName | sort eventTime desc
    

    The above formula directs Amazon CloudWatch Log Insights to display the event time, user name and access key of the identity that performed the control plane operation, the ip address from where the operation was performed, the AWS region inside which the operation was performed, the event’s source and name. The results are sorted based on the event time in descending order.

    Next, set the time range for events that CloudWatch Logs Insights must process. To configure this, pick the appropriate duration from those displayed on the top right (as displayed inside the green rectangle in the screenshot above). For my setup, I chose 1hr.

    Once completed, click Create widget

  7. The next screen should look similar the screenshot below. Click Save dashboard

     

    Amazon CloudWatch Logs Insights - Create Dashboard

  8. Your Amazon CloudWatch dashboard is now complete. To refresh the events, you can press the refresh button (pointed by the red arrow in the screenshot
  9. Amazon CloudWatch Logs Insights - Refresh Events
  10. You can also enable auto refresh of the events by clicking the small arrow beside the refresh button. You will get a menu option similar to the screenshot below.

    Tick Auto refresh and choose the Refresh interval of your choice.

  11. Pro Tip 1 – if you want your dashboard to be displayed under the Favorite section when you open the Amazon CloudWatch service page, go into the Dashboards section of Amazon CloudWatch and click on Favorite (star) beside your dashboard name.
  12. Pro Tip 2 – If you want your dashboard to appear on the default Amazon CloudWatch service page, rename your dashboard to CloudWatch-Default.
  13. Pro Tip 3 = at the beginning of each row In your dashboard, you will notice a small arrow head. If you click on the arrow head, it expands that event and provides additional information.

Thats it! You should now have a dashboard similar to the one below that shows the control plane operations as they happen.

Amazon CloudWatch Logs Insights Dashboard

At times, I found there to be approximately five minutes of delay between when the event happened and when it was displayed. This could be due to the delay between when the event was generated and when that service that generated it delivered the logs to AWS CloudTrail.

The dashboard should allow you to easily monitor any suspicious control plane activities in your AWS account.

I hope the above was useful. Till the next time, Enjoy!

Creating a Contact Center in minutes using Amazon Connect

Background

In my previous blog (https://nivleshc.wordpress.com/2019/10/09/managing-amazon-ec2-instances-using-amazon-ses/), I showed how we can manage Amazon EC2 instances using emails. However, what if you wanted to go further than that? What if, instead of sending an email, you instead wanted to dial in and check the status of or start/stop your Amazon EC2 instances?

In this blog, I will show how I used the above as a foundation to create my own Contact Center. I enriched the experience by including an additional option for the caller, to be transferred to a human agent. All this in minutes! Still skeptical? Follow on and I will show you how I did all of this using Amazon Connect.

High Level Solution Design

Below is the high-level solution design for the Contact Center I built.

The steps (as denoted by the numbers in the diagram above) are explained below

  1. The caller dials the Direct Inward Dial (DID) number associated with the Amazon Connect instance
  2. Amazon Connect answers the call
  3. Amazon Connect invokes the AWS Lambda function to authenticate the caller.
  4. The AWS Lambda function authenticates the caller by checking their callerID against the entries stored in the authorisedCallers DynamoDB table. If there is a match, the first name and last name stored against the callerID is returned to Amazon Connect. Otherwise, an “unauthorised user” message is returned to Amazon Connect.
  5. If the caller is unauthorised, Amazon Connect informs them of this and hangs up the call.
  6. If the caller is authorised, Amazon Connect uses the first name and last name provided by AWS Lambda function to personalise a welcome message for them. Amazon Connect then provides the caller with two options:
      •  (6a) press 1 to get the status of the Amazon EC2 instances. If this is pressed, Amazon Connect invokes an AWS Lambda function to get the status of the Amazon EC2 instances and plays the results to the caller
      • (6b) press 2 to talk to an agent. If this is pressed, Amazon Connect places the call in a queue,  where it will be answered by the next available agent

     

Preparation

My solution requires the following components

  • Amazon DynamoDB table to store authorised callers (an item in this table will have the format phonenumber, firstname,  lastname)
  • AWS Lambda function to authenticate callers
  • AWS Lambda function to get the status of all Amazon EC2 instances in the region

I created the following AWS CloudFormation template to provision the above resources.

The above AWS CloudFormation template can be downloaded from https://gist.github.com/nivleshc/926259dbbab22dd4890e0708cf488983

Implementation

Currently AWS CloudFormation does not support Amazon Connect. The implementation must be done manually.

Leveraging on my own experience with setting up Amazon Connect solutions,  I observed that there are approximately three stages that are required to get a Contact Center up and running. These are:

  • Provisioning an Amazon Connect instance – this is straight forward and essentially is where an Amazon Connect instance is provisioned and made ready for your use
  • Configuring the Amazon Connect instance – this contains all the tasks to customise the Amazon Connect instance. It includes the configuration of the Direct Inward Dial (DID), hours or operations for the Contact Center, Routing profiles, users etc
  • Creating a custom Contact flow – a Contact flow defines the customer experience of your Contact Center, from start to finish. Amazon Connect provides a few default Contact flows however it is highly recommended that you create one that aligns with your own business requirements.

Follow along and I will show you how to go about setting up each of the above mentioned stages.

Provision the Amazon Connect Instance

  1. From the AWS Console, open the Amazon Connect service. Select the Sydney region (or a region of your choice, however do keep in mind that at the moment, Amazon Connect is only available in a few regions)
  2. Enter an Access URL for your Amazon Connect Instance. This URL will be used to access the Amazon Connect instance once it has been provisioned.
  3. In the next screen, create an administrator account for this Amazon Connect instance
  4. The next prompt is for Telephony options. For my solution, I selected the following:
    1. Incoming calls: I want to handle incoming calls with Amazon Connect
    2. Outgoing calls: I want to make outbound calls with Amazon Connect
  5. In the next screen, Data Storage options are displayed. For my solution, I left everything as default.
  6. In the next screen, review the configuration and then click Create instance

Configure the Amazon Connect Instance

After the Amazon Connect instance has been successfully provisioned, use the following steps to configure it:

  1. Claim a phone number for your Amazon Connect Instance. This is the number that users will be calling to interact with your Amazon Connect instance (for claiming non toll free local numbers, you must open a support case with AWS, to prove that you have a local business in the country where you are trying to claim the phone number. Claiming a local toll-free number is easier however it is more expensive)
  2. Create some Hour of operation profiles. These will be used when creating a queue
  3. Create a queue. Each queue can have different hours of operation assigned
  4. Create a routing profile. A user is associated with a routing profile, which defines their inbound and outbound queues.
  5. Create users. Once created, assign the users to a predefined security profile (administrator, agent etc) and also assign them to a specific routing profile

Create a custom Contact flow

A Contact flow defines the customer experience of your Contact Center, from start to finish. By default, Amazon Connect provides a few Contact flows that you can use. However, it is highly recommended that you create one that suits your own business requirements.

To create a new Contact flow, follow these steps:

  • Login to your Amazon Connect instance using the Access URL and administrator account (you can also access your Amazon Connect instance using the AWS Console and then click on Login as administrator)
  • Once logged in, from the left-hand side menu, go to Routing and then click on Contact flows
  • In the next screen, click on Create contact flow
  • Use the visual editor to create your Contact flow

Once the Contact flow has been created, attach it to your Direct Inward Dial (DID) phone number by using the following steps:

  • from the left-hand side menu, click on Routing and then Phone numbers.
  • Click on the respective phone number and change its Contact flow / IVR to the Contact flow you want to attach to this phone number.

Below is a screenshot of the Contact flow I created for my solution. It shows the flow logic I used and you can easily replicate it for your own environment. The red rectangles show where the AWS Lambda functions (mentioned in the pre-requisites above) are used.

This is pretty much all that is required to get your Contact Center up and running. It took me approximately thirty minutes from start to finish (this does not include the time required to provision the Amazon DynamoDB tables and AWS Lambda functions). However, I would recommend spending time on your Contact flows as this is brains of the operation. This must be done in conjunction with someone who understands the business really well and knows the outcomes that must be achieved by the Contact Center solution. There is a lot that can be done here and the more time you invest in your Contact flow, the better outcomes you will get.

The above is just a small part of what Amazon Connect is capable of. For its full set of capabilities, refer to https://aws.amazon.com/connect/

So, if you have been dreaming of building your own Contact Center, however were worried about the cost or effort required? Wait no more! You can now easily create one in minutes using Amazon Connect and pay for only what you use and tear it down if you don’t need it anymore. However, before you start, I would strongly recommend that you get yourself familiar with the Amazon Connect pricing model. For example – you get charged a daily rate for any claimed phone numbers that are attached to your Amazon Connect Instance (this is similar to a phone line rental charge). Full pricing is available at https://aws.amazon.com/connect/pricing/).

I hope the above has given you some insights into Amazon Connect. Till the next time, Enjoy!

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!