Conditionally enable x-ray for API Gateway and Lambda in serverless framework - aws-lambda

I am trying to enable x-ray only when I needed to save some bucks. The following serverless.yml loads the environment variables from the .env file. However, it seems like serverless only allows true, Active and PassThrough. Any possible way to bypass this? Thanks.
# serverless.yml
provider:
name: aws
runtime: nodejs10.x
logs:
restApi: ${env:ENABLE_X_RAY, false}
tracing:
apiGateway: ${env:ENABLE_X_RAY, false}
lambda: ${env:ENABLE_X_RAY, false}
plugins:
- serverless-dotenv-plugin
# .env
ENABLE_X_RAY=true

If the entry point of your service is API Gateway you can configure Sampling Rules and limits on the AWS X-Ray console or using API to control the number of requests that are sampled by X-Ray.
See this article for an introduction to sampling in X-Ray:
https://aws.amazon.com/blogs/aws/apigateway-xray/
Let me know if you have further questions regarding this.
Update
Sampling rules may be specified only in X-Ray.
https://docs.aws.amazon.com/xray/latest/devguide/xray-console-sampling.html
This allows you to limit the number of traces no matter how many API Gateway or EC2 instances you have for handling your requests.
Small caveat: As of today, this mode of sampling is supported only if the entry point is API Gateway or if you have the >2.0 version of X-Ray daemon running on your instances (EC2 or otherwise). If the entry point is lambda this sampling effect is not supported today but will be supported soon.
In your case it seems you are using API Gateway as your entry point, so you can definitely configure sampling rules in X-Ray console and have that take effect globally across all your API Gateway endpoints.
You can also configure different sampling rules for different URLs like /auth is sampled at 5 TPS and /products is configured for 1 TPS with different reservoirs based on your usecase.

Related

How does functions as a service ( FaaS) hosting work under the hood?

hypothesis
Suppose I want to roll out my own FaaS hosting, a service like Lambda, not on Lambda.
analogy
I have an abstract understanding of other cloud services as follows
1. Infrastructure as a service (IaaS): Create virtual machines for tenants on your hardware.
2. Platform as a service (PaaS): Create VM and run script that loads the required environment.
The above could also be achieved with docker images.
What about FaaS?
AWS uses firecracker VM for Lambda functions. But what's not clear is how the VMs are triggered on and off, how they're orchestrated on multiple pieces of hardware in a multi-tenant environment. Could someone explain how the complete life cycle works?
The main features of AWS Lambda and Cloud Function can be found in
https://cloud.google.com/docs/compare/aws/compute#faas_comparison
I can include the information of what I know, that is Google Cloud Functions.
Triggers
Cloud Functions can be triggered in two ways: HTTP request or Event-triggered. Events and Triggers. The events are things that happen into your project: A file is updated in Cloud Storage or Cloud Firestore. Other events are: a Compute Engine instance (VM) is initialized or the source code is updated in your repository.
All these events can be the trigger of a Cloud Function. This function, when triggered, is executed in a VM that will receive a HTTP request, and context information to perform its duty.
Auto-scaling and machine-type
If the volume that arrives to a Cloud Function increases, it auto-scales. That is that instead of having one VM executing one request at a time. You will have more than one VMs that server one request at a time. In any instance, only one request at a time will be analyzed.
If you want more information, you can check it on the official documentation.

How to apply Serverless to an existing API gateway

Recently I use Serverless framework do create/deploy AWS lambda function / API gateway. It's a very cool way to deploy Lambda/API but I don't know how to apply it to existing AWS lambdas / APIs.
Is there any way to do it without drop the existing one then re-creating using serverless because i have dozens of existing lambda functions and apis.
https://www.serverless.com/framework/docs/providers/aws/events/apigateway/#share-api-gateway-and-api-resources
As your application grows, you will likely need to break it out into multiple, smaller services. By default, each Serverless project generates a new API Gateway. However, you can share the same API Gateway between multiple projects by referencing its REST API ID and Root Resource ID in serverless.yml as follows:
service: service-name
provider:
name: aws
apiGateway:
restApiId: xxxxxxxxxx # REST API resource ID. Default is generated by the framework
restApiRootResourceId: xxxxxxxxxx # Root resource, represent as / path
websocketApiId: xxxxxxxxxx # Websocket API resource ID. Default is generated by the framework
description: Some Description # optional - description of deployment history
functions: ...
No. You can reuse the lambda functions by pointing to the specific ARN's of those functions within Serverless.yml, but there is currently no way to "replace" the API Gateway component without manual intervention and re-creation using Serverless.
The upside is, it should be relatively straightforward and easy to do unless you use features in AWS API Gateway currently not supported by the Serverless framework.

Global borderless implementation website/app on Serverless AWS

I am planning to use AWS to host a global website that have customers all around the world. We will have a website and app, and we will use serverless architecture. I will also consider multi-region DynamoDB to allow users closer to the region to access the closest database instance.
My question regarding the best design to implement a solution that is not locked down to one particular region, and we are a borderless implementation. I am also looking at high traffic and high number of users across different countries.
I am looking at this https://aws.amazon.com/getting-started/serverless-web-app/module-1/ but it requires me to choose a region. I almost need a router in front of this with multiple S3 buckets, but don't know how. For example, how do users access a copy of the landing page closest to their region?, how do mobile app users call up lambda functions in their region?
If you could point me to a posting or article or simply your response, I would be most grateful.
Note: would be interested if Google Cloud Platform is also an option?
thank you!
S3
Instead of setting up an S3 bucket per-region, you could set up a CloudFront distribution to serve the contents of a single bucket at all edge locations.
During the Create Distribution process, select the S3 bucket in the Origin Domain Name dropdown.
Caveat: when you update the bucket contents, you need to invalidate the CloudFront cache so that the updated contents get distributed. This isn't such a big deal.
API Gateway
Setting up an API Gateway gives you the choice of Edge-Optimized or Regional.
In the Edge-Optimized case, AWS automatically serves your API via the edge network, but requests are all routed back to your original API Gateway instance in its home region. This is the easy option.
In the Regional case, you would need to deploy multiple instances of your API, one per region. From there, you could do a latency-based routing setup in Route 53. This is the harder option, but more flexible.
Refer to this SO answer for more detail
Note: you can always start developing in an Edge-Optimized configuration, and then later on redeploy to a Regional configuration.
DynamoDB / Lambda
DynamoDB and Lambda are regional services, but you could deploy instances to multiple regions.
In the case of DynamoDB, you could set up cross-region replication using stream functions.
Though I have never implemented it, AWS provides documentation on how to set up replication
Note: Like with Edge-Optimized API Gateway, you can start developing DynamoDB tables and Lambda functions in a single region and then later scale out to a multi-regional deployment.
Update
As noted in the comments, DynamoDB has a feature called Global Tables, which handles the cross-regional replication for you. Appears to be fairly simple -- create a table, and then manage its cross-region replication from the Global Tables tab (from that tab, enable streams, and then add additional regions).
For more info, here are the AWS Docs
At the time of writing, this feature is only supported in the following regions: US West (Oregon), US East (Ohio), US East (N. Virginia), EU (Frankfurt), EU West (Ireland). I imagine when enough customers request this feature in other regions it would become available.
Also noted, you can run Lambda#Edge functions to respond to CloudFront events.
The lambda function can inspect the AWS_REGION environment variable at runtime and then invoke (and forward the request details) a region-appropriate service (e.g. API Gateway). This means you could also use Lambda#Edge as an API Gateway replacement by inspecting the query string yourself (YMMV).

How do I protect myself from AWS Lambda abuse?

I'm creating a serverless website using AWS Lambda, but I'm a bit concerned about potential abuse. How do I protect myself against a user who queries my endpoint a million times?
The API Gateway supports throttling. The defaults are reasonable, but you can alter them however you like. The throttle settings in the console are under the Stages tab of you APIs. There's more info here: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html

Does Serverless Framework support any kind of multi-cloud load balancing?

Does Serverless Framework support the ability to deploy the same API to multiple cloud providers (AWS, Azure and IBM) and route requests to each provider based on traditional load balancer methods (i.e. round robin or latency)?
Does Serverless Framework support this function directly?
Does Serverless integrate with global load balancers (e.g. dyn or neustar)?
Does Serverless Framework support the ability to deploy the same API to multiple cloud providers (AWS, Azure and IBM)
Just use 3 different serverless.yml files and deploy each function 3 times.
and route requests to each provider based on traditional load balancer methods (i.e. round robin or latency)?
No, there is no such support for multi-cloud load balancing
The Serverless concept is based on trust: you trust that your Cloud provider will be able to handle your traffic with proper scalability and availability. There is no multi-cloud model, a single Cloud provider must be able to satisfy your needs. To achieve this, they must implement a proper load-balacing schema internally.
If you don't trust on your Cloud provider, you are not thinking in a serverless way. Serverless means that you should not worry about the infra the supports your app.
However, you can implement a sort of multi-cloud load balancing
When you specify a serverless.yml file, you must say which provider (AWS, Azure, IBM) will create those resources. Multi-cloud means that you need one serverless.yml file per each Cloud, but the source code (functions) can be the same. When you deploy the same function to 3 different providers, you will receive 3 different endpoints to access them.
Now, which machine will execute the Load Balance? If you don't trust that a single Cloud provides enough availability, how will you define who will serve the Load Balance feature?
The only solution that I see is to implement this load-balacing in your frontend code. Your app would know the 3 different endpoints and randomize the requests. If one request returns an error, the endpoint would be marked as unhealthy. You could also determine the latency for each endpoint and select a preferred provider. All of this in the client code.
However, don't follow this path. Choose just one provider for production code. The SLA (service level agreement) usually provides a high availability. If it's not enough, you should still stick with just one provider and have in hand some scripts to easily migrate to another cloud in case of a mass outage of your preferred provider.

Resources