Server vs Serverless for REST API - mysql

I have a REST API that I was thinking about deploying using a Serverless model. My data is in an AWS RDS server that needs to be put in a VPC for security reasons. To allow a Lambda to access the RDS, I need to configure the lambda to be in a VPC, but this makes cold starts an average of 8 seconds longer according to articles I read.
The REST API is for a website so an 8 second page load is not acceptable.
Is there anyway I can use a Serverless model to implement my REST API or should I just use a regular EC2 server?

Unfortunately, this is not yet released, but let us hope that this is a matter of weeks/months now. At re:Invent 2018 AWS has introduced Remote NAT for Lambda to be available this year (2019).
For now you have to either expose RDS to the outside (directly or through a tunnel), but this is a security issue. Or Create Lambda ENIs in VPC.
In order to keep your Lambdas "warm" you may create a scheduled "ping" mechanism. Some example of this pattern you can find in the Article of Yan Cui.

Related

Connect to private Amazon RDS without EC2

I see a lot of articles online where EC2 is involved, but since my backend is essentially serverless I have not found much information how to access my RDS once it is turned private. Can anyone point me in the right direction?
Current state:
Public MySQL RDS
RDS is accessed by a MySQL client on my local machine (MySQL Workbench) and AWS Lambda functions via my web application (both connecting via SSL)
Future state:
Private MySQL RDS
Private RDS would continue to be accessed by only my local machine and only the noted AWS Lambda functions via my web application (I assume continuing to use SSL?)
In your scenario your Lambda functions will need to be configured to run in the VPC if they are not already. That is the only change required for the Lambda functions.
However, When you switch the RDS instance to private, that means it only accepts connections from within the VPC. So you can't make connections directly from your local computer to the database anymore. You have to go through some sort of "bridge" to get your local computer into the AWS VPC network.
In this scenario people either use an EC2 instance as a bastion host, or they create a VPN connection from their local computer into the AWS VPC. AWS Client VPN is a managed service you could used for this.
You'll need to evaluate the Client VPN pricing, but I think you may find that a single t4g.nano EC2 bastion host is probably cheaper, and you can also stop the instance when you don't need it to really cut down the cost.
You can use VPC also with Lambda. Lambda and RDS can be in the same VPC, or in separate VPC’s peered together. Aws documentation for this scenario can be found here: https://aws.amazon.com/premiumsupport/knowledge-center/connect-lambda-to-an-rds-instance/
You can use Basti, which is a CLI tool that manages the EC2 bastion instance for you. The tool keeps the instance stopped when it's not used to minimize the solution cost, performs software updates to maintain the bastion instance secure, and provides a convenient CLI that can be used locally and in CI/CD pipelines.

Unable to connect to MySQL instance running on AWS EC2 from AWS Lambda function

I am writing an AWS Lambda function to connect to a MySQL instance running on EC2. I have associated the Lambda function with the same subnet and security group that the EC2 is configured in. I checked the Lambda function's IAM roles and that has AWSLambdaVPCAccessExecutionRole policy attached to it. However I am still not able to connect to the MySQL instance.
I tried allowing traffic from anywhere and that worked but now I am not sure how to connect to the MySQL instance with stricter security rules.
I am using Kotlin to write my lambda function and using serverless to deploy changes to lambda.
I have tried every possible solution available online to make this happen but I haven't had any positive results yet.
You have associated the Lambda function with the same security group. But just that would not do. You also need to add an ingress rule to allow traffic to the security group from itself. Basically, you need to self reference the security group.
Add a rule to allow traffic on the mysql port from sg-xxxxxxxx.

AWS RDS MySQL database username and password sufficient for commercial security

I'm new to cloud computing so this might be an obvious question. I have a desktop Java application that will connect to an AWS RDS MySQL database using JDBC. Is using the endpoint, username and password for the database the preferred commercial way of connecting to the database?
To encrypt communication I plan to use SSL.
You could open your database instance to the outside, using regular credentials. But, a safer way to proceed might be to create an endpoint in AWS, possibly running in Java, which would expose one or more APIs which in turn would hit the MySQL database running in RDS. That is, you would not expose the RDS instance to the outside world directly, but only internally to this API, also running in AWS. Then, your desktop Java application would talk to this intermediary application when it needs to access the database.
The advantage of this suggestion is that it lessens the risk of your RDS instance being attacked via something like DOS. Of course, the API you create on top of the database could also be attacked. But, Java web application running in a container (and other similar applications in other languages) were designed to be exposed to the outside, much less so database instances.

What is the difference between Serverless containers and App Engine flexible with custom runtimes?

I came across the article : Bringing the best of serverless to you
where I came to know about upcoming product called Serverless containers on Cloud Functions which is currently in Alpha.
As described in the article:
Today, we’re also introducing serverless containers, which allow you
to run container-based workloads in a fully managed environment and
still only pay for what you use.
and in GCP solutions page
Serverless containers on Cloud Functions enables you to run your own containerized workloads on
GCP with all the benefits of serverless. And you will still pay only
for what you use. If you are interested in learning more about
serverless containers, please sign up for the alpha.
So my question is how this serverless containers different from app engine flexible with custom runtime, which also use a docker file?
And it's my suspicion, since mentioned named is Serverless containers on Cloud Functions, the differentiation may include role of cloud functions. If so what is the role played by cloud functions in the serverless containers?
Please clarify.
What are Cloud Funtions?
From the official documentation:
Google Cloud Functions is a serverless execution environment for building and connecting cloud services. With Cloud Functions you write simple, single-purpose functions that are attached to events emitted from your cloud infrastructure and services. Your function is triggered when an event being watched is fired. Your code executes in a fully managed environment. There is no need to provision any infrastructure or worry about managing any servers.
In simple words, the Cloud Function is triggered by some event (HTTP request, PubSub message, Cloud Storage file insert...), runs the code of the function, returns a result and then the function dies.
Currently there are available four runtime environments:
Node.js 6
Node.js 8 (Beta)
Python (Beta)
Go (Beta)
With the Serverless containers on Cloud Functions product it is intended that you can provide your own custom runtime environment with a Docker Image. But the life cycle of the Cloud Function will be the same:
It is triggered > Runs > Outputs Result > Dies
App Engine Flex applications
Applications running in the App Engine flexible environment are deployed to virtual machines, i.e Google Cloud Compute Engine instances. You can choose the type of machine you want use and the resources (CPU, RAM, disk space). The App Engine flexible environment automatically scales your app up and down while balancing the load.
As well as in the case of the Cloud Functions there runtimes provided by Google but if you would like to use an alternative implementation of Python, Java, Node.js, Go, Ruby, PHP, .NET you can use Custom Runtimes. Or even you can work with another language like C++, Dart..., you just need to provide a Docker Image for your Application.
What are differences between Cloud Functions and App Engine Flex apps?
The main difference between them are its life cycle and the use case.
As commented above a Cloud Function has a defined life cycle and it dies when it task concludes. They should be used to do 1 thing and do it well.
On the other hand an Application running on the GAE Flex environment will always have at least 1 instance running. The typical case for this applications are to serve several endpoints where users can do REST API calls. But they provide more flexibility as you have full control over the Docker Image provided. You can do "almost" whatever you want there.
What is a Serverless Container?
As stated on the official blog post (search for Serverless Containerss), it's basically a Cloud Function running inside a custom environment defined by the Dockerfile.
It is stated on the official blog post:
With serverless containers, we are providing the same underlying
infrastructure that powers Cloud Functions, but you’ll be able to
simply provide a Docker image as input.
So, instead of deploying your code on the CF, you could also just deploy the Docker image with the runtime and the code to execute.
What's the difference between this Cloud Functions with custom runtimes vs App Engine Flexible?
There are 5 basic differences:
Network: On GAE Flexible you can customize the network the instances run. This let's you add firewalls rules to restrict egress and ingress traffic, block specific ports or specify the SSL you wish to run.
Time-Out: Cloud Functions can run for a maximum of 9 minutes, Flexible on the other hand, can run indefinitely.
Ready only environment: Cloud Functions environment is read-only while Flexible could be written (this is only intended to store spontaneous information as once the Flexible instance is restarted or terminated, all the stored data is lost).
Cold Boot: Cloud Functions are fast to deploy and fast to start compared to Flexible. This is because Flexible runs inside a VM, thus this extra time is taken in order for the VM to start.
How they work: Cloud functions are event driven (ex: upload of photo to cloud storage executing a function) on the other hand flexible is request driven.(ex: handling a request coming from a browser)
As you can see, been able to deploy a small amount of code without having to take care of all the things listed above is a feature.
Also, take into account that Serverless Containers are still in Alpha, thus, many things could change in the future and there is still not a lot of documentation explaining in-depth it's behavior.

AWS SQS to receive message from outside of AWS

my company has a messaging system which sends real-time messages in JSON format, and it's not built on AWS, and will not have any VPN connection with AWS.
our team is trying to use AWS SQS to receive these messages, which will then have DynamoDB process JSON messages to TSV, then load into RDS.
however, as per the FAQ, SQS can only receive message from within AWS.
https://aws.amazon.com/sqs/faqs/
Q: Who can perform operations on a message queue?
Only an AWS account owner (or an AWS account that the account owner has delegated rights to can perform operations on an Amazon SQS message queue.
In order to use SQS, one way I can think of is to create a public-facing EC2 instance, which receives messages and passes over to SQS.
My questions here are:
is my idea correct?
if it's correct, can you share any details on how to build any applications on this EC2 instance to achieve the functionality (I have no experience on application development, your insights are really appreciated!)
is there any easier/better options in AWS that can achieve the goal to receive message in my use case?
is my idea correct?
No, it isn't.
You're misinterpreting the (admittedly somewhat unclear) information in the FAQ.
SQS is accessible and usable from anywhere on the Internet. Its only exposed interface is HTTP(S). In fact, from inside EC2, SQS is not accessible unless the EC2 instance actually has outbound access to the Internet.
The point being made in the documentation is not that you need to be "inside" AWS to use queues, but rather that you need to be in possession of an authorized set of AWS credentials in order to work with queues.¹
If you have an AWS account, you have credentials, and you can use SQS. There is no requirement that you access the queue from "inside" AWS.
Choose the endpoint closest to your servers (for lowest latency) and you should find it open and accessible, from anywhere.
¹Queues can be configured to allow anonymous acccess after they are created. (Don't do it, I'm just saying it is possible.) This section of the FAQ seems to be referring to a subset of operations, such as creating queues.
I was not able to write to SQS from an external service. I found some partial explanations but got stuck at the role creation.
The alternative I found is using AWS services Lambda + API Gateway to write to SQS.
This tutorial was extremely helpful, explaining all the steps in great details:
https://startupnextdoor.com/adding-to-sqs-queue-using-aws-lambda-and-a-serverless-api-endpoint/
You can access sqs from anywhere once you have proper permission through accesskey&secret key or IAM role.
SQS is not specific to vpc
It is clear that you try to do this :
Take message from your company messaging system, send it to SQS.
It is not wrong using your method (using EC2 as a bridge). However, you don't need EC2 to connect to SQS.
All AWS services can be access using AWS API(e.g. Python boto3, etc) from internet, as long as you provide the correct credential. So you can put your "middleware" in anywhere as long as you are able establish connection to the said services.
So there is lots of more options available to you. e.g. trigger from your messaging system; use AWS Lambda, etc.
Thanks for sharing the information and your insights with me!
I have tested below solution, which works for my use case:
created an endpoint in AWS API Gateway, which is able to receive messages from company messaging system, a system that does not carry AWS credentials
created a Lambda function triggered by API Gateway, so once a message arrives, Lambda will digest the JSON message and convert it to TSV, and then load into RDS