You’re an Ops person who’s ready to take a dip into AWS Lambda and this whole serverless thing. But where do you start? You’ve gone from deploying a monolith to deploying microservices. Now how do you go from deploying a microservice to deploying functions?
We want to take something that was originally written to run on an EC2 instance and run it on Lambda. How do we get there? In this post, we’ll explore this question by looking at the threatstack-to-s3 service that we’ve discussed in other blog posts.
But before we start rewriting this service, let’s take a step back and start thinking about what we’re trying to do and the issues we need to deal with. Specifically, let’s start the discussion by examining three key issues you need to consider before you go any further:
- Whether to use API Gateway or not
- How much Lambda will actually cost you in production
- How to take care of security (specifically, AWS access controls and secrets management)
Once we’ve covered these three bases in this post, we’ll go into more depth in future posts.
AWS Lambda and API Gateway (maybe)
When using AWS Lambda, you might decide to use API Gateway, but it’s not essential that you do. While it is the shortest way to get up and running, there are pros and cons that you need to consider.
When writing a microservice, we’re used to an endpoint and a function going hand in hand:
@s3.route('/api/v1/s3/alert', methods=['POST']) def put_alert(): ''' Archive Threat Stack alerts to S3. '''
If we do an HTTP POST to the /api/v1/s3/alert endpoint with alert data, then the alert will be archived in S3. This is not the case with AWS Lambda functions. AWS Lambda functions are just that — functions, not endpoints. Lambda functions can be invoked in a variety of ways which include:
- API Gateway
- SQS (via scheduled execution)
- And others
The AWS Lambda function and the method for invoking it are two separate things, and this is one area that you will have to better understand in order to use AWS Lambda effectively. What does that mean? Consider an AWS SNS topic and HTTPS subscribers, for example:
This topic publishes to several HTTPS endpoint subscribers on AWS API Gateway, which are configured with Lambda functions behind those endpoints. It doesn’t have to be set up that way, however. With some refactoring of these existing services, it would be possible to skip API Gateway and subscribe to the function directly:
We will focus on using API Gateway because it requires the least refactoring of our existing apps in order to get up and running. But it is important to remember that AWS Lambda is for our functions, and AWS API Gateway is for our endpoints. (We’ll discuss how that relationship works in greater detail in a future blog post. In fact, our Lambda functions will still use the API path because of how we’ve chosen to refactor our application.)
Just as determining whether or not you are going to use an API Gateway is an important consideration, another factor you need to take into account is how much Lambda is going to cost you. One of the great things about Lambda is the fact that it is pay per use. That makes it ideal for periodic use service, and the threatstack-to-s3 service fits that definition perfectly. (Well, hopefully it does. If it doesn’t, then you either need to tune your Threat Stack rules, or I don’t envy the number of threats you’re facing.)
To make some rough cost calculations, sketch out a plan that walks you through the process of deploying the threatstack-to-s3 service to an EC2 instance. Run threatstack-to-s3 on one small instance, a t2.nano, the smallest:
So running threatstack-to-s3 amounts to $4.32/month in EC2 costs.
Well, not exactly.
Let’s start getting this service ready to run in the real world. Hypothetically, the service needs to be reliable enough so we don’t lose alerts and fail to archive them. We’re going to want more instances of this service. We’ll settle on three instances to match the number of Availability Zones (AZ) we have in use in us-east-1. We’ll also want an Elastic Load Balancer (ELB) to front these instances:
The bill has gone from $4.32/month to $31.26/month. That’s $12.96 for the EC2 instances and $18.30 for the ELB.
Many folks can stop here and be fine, but others of us still have more to do in order to get threatstack-to-s3 production ready. If you’re not yet at immutable infrastructure, then you possibly have some agents to run on there, such as Puppet or Chef. Based on previous experience, I don’t run those on systems smaller than a t2.medium due to issues with resource exhaustion. (Note: This may be an outdated issue; I haven’t tested this in awhile.)
That brings the bill up to $121.53 per month to store an alert in S3.
There are probably multiple other agents running on the host as well for health monitoring, metrics collection, log shipping, and security monitoring. Some of those services may have their own costs associated with them due to SaaS charges.
Let’s hypothetically price out the cost on AWS Lambda based on 10,000 alerts per month:
Using AWS API Gateway, you will also incur a charge of $3.50/month for the first million requests, resulting in a grand total of $3.71 per month.
This price difference may or may not actually be a big deal to you depending on your scale. For some infrastructures, $121/month is still a rounding error. But what’s the tipping point when it makes sense to run on EC2 instead of Lambda; the point where the number of requests outweighs the costs of running a host full time? That we’ll have to experiment on in order to find an answer.
AWS Lambda and Security
Finally let’s think about security and Lambda — in particular AWS access controls and secrets management. If we were deploying threatstack-to-s3, we would need an EC2 instance with the ability to read and write to an S3 bucket. We would accomplish that by creating EC2 instances with an IAM role attached to the EC2 instance that allowed write access to the bucket. The number of people in an organization who can create IAM policies and roles is typically pretty limited due to the amount of power it grants someone.
Let’s think of how threatstack-to-s3 might get out the door in a typical environment. A developer writes a service and needs to deploy it to a host and have the ability to read and write to an S3 bucket. Ops writes a Terraform configuration or CloudFormation template that creates an IAM role and policy with the necessary S3 permissions and an ASG configured with a Launch Configuration to utilize that role. Once the initial AWS resources are configured, a developer can deploy their service at will without the need for Ops via a continuous deployment pipeline.
How would the process work with Lambda? We want a developer to be able to easily deploy new versions of the Lambda function, but we don’t want them to be able to create and modify IAM roles and policies. What do the deployment and operational responsibilities for a Lambda function involve? What does the Terraform or CloudFormation for that look like? How can we safely continue to allow developers to be able to deliver services quickly without granting them wide-ranging permissions to the environment?
Final Words . . .
As we pointed out earlier, before you start moving services to AWS Lambda, it’s important to understand some of the key underlying issues, including whether you should use API Gateway or not, what the actual costs of using Lambda will be, and how to ensure that you’re taking care of security issues (AWS access controls and secrets management).
In future posts, we’ll build on this information, going into depth on how to rewrite a service for AWS Lambda.
If your organization is just starting out in cloud security, be sure to download a free copy of our Jump Starting Cloud Security playbook.
It has everything you need to increase security across your organization while establishing a foundation that will help you scale security as your organization grows and its needs become more complex.