Keep two versions of AWS Lambdas running - amazon-web-services

Simple explanation of my current infrastructure: I am using AWS Lambdas (running python code there), which are deployed via the Gitlab CI using serverless framework.
Explanation of situation: I currently have an AWS Lambda which uses a specific library version (for now say version 1.x.x). At some point in time, this Lambda will start using a new version of the this library (say 2.x.x), but I want both of these lambdas to be still deployed and available to handle requests.
If at some other point in time the version 3.x.x of the library comes, I want to keep the lambda using version 3.x.x and 2.x.x running (basically the current version and current version - 1 lambdas). Lets call them Lambda_NEW and Lambda_OLD.
AWS lambdas have the concepts of versions and aliases which could be used, but unfortunately they are not supported by serverless directly.
Note: serverless supports multiple versions (which cannot be named) and there is a plugin called serverless-aws-aliases which can set aliases for you, but that one refer to the actual AWS Lambda versions (see https://github.com/serverless-heaven/serverless-aws-alias/issues/148).
Do you have any idea on how to tackle it?
My only valid thought so far is to keep two branches (NEW and OLD) which will use two different versions of the library, and each branch will have its different deploy CI. This is very counter intuitive though, since I don't know how to maintain develop and master branches. Also, when to deploy to which stage etc.
Also I somehow want both Lambda_NEW and Lambda_OLD to be deployed on the same time (e.g. when switching to library 5.x.x, I want version 5.x.x to be in the NEW and version 4.x.x in the old)

I'm not sure from your post, but I gather that you want a way to handle canary deployments, so that you could easily roll back changes? If that's not the case, could you edit your question and provide a bit more clarity?
If that's the case, I'd recommend following this guide and using the canary-deployments plugin, which will automatically create aliases for new versions, and allows you to define how traffic is shifted between deployed versions.

Related

Update Lambda function to use latest layer

I have a fairly simple GitHub action that deploys my Lambda functions in addition to updating the layers that they use. However after doing so, the functions continue to use the old version of the layer. I have to go in to the console and manually update the functions to use the new layers.
Is there any way to do this via the cli or similar?
I know it's possible to specify a layer and version for a function with that, but I can't see a way to automatically set it to the latest version of the layer.
Here's my current action for deployment, for reference - https://github.com/Jademalo/JadeBots/blob/aws-lambda/.github/workflows/lambda-deploy.yml

Where can I find the source code for AWS Lambda's dotnetcore3.1 runtime?

AWS publishes a lot of their source code on GitHub, but so far I haven't been able to find the source for the dotnetcore3.1 Lambda Runtime.
I expect this source will be a console application responsible for startup and IoC (using the Lambda configuration to determine the handler class and function, using reflection to instantiate the handler, as well as the serializer specified on the lambda's assembly attribute). So far I have found a number of repositories containing things like NuGet libraries and dotnet CLI tooling--but haven't located the runtime itself.
Is the AWS Lambda dotnetcore3.1 runtime source publically available? Can you point me to the repo and .csproj? Thanks!
I am not 100% sure, but there is probably nothing like a dedicated ".NET Core Runtime" that is publicly available.
Let's explore how Lambda works to explain why I think that:
First there is an EC2 instance with a host operating system. That's the bare metal your resources are coming from (vCPU, RAM, disk, etc.).
Second, there is a thin management layer for microVMs. For AWS Lambda this is a project called Firecracker.
The microVMs that are started use a micro kernel. In case of AWS Lambda it is the OSv micro kernel. The micro kernel already has some support for runtimes:
OSv supports many managed language runtimes including unmodified JVM, Python 2 and 3, Node.JS, Ruby, Erlang as well as languages compiling directly to native machine code like Golang and Rust.
.NET Core is compiled so I think this falls into the same category. It is a "native" binary, that is self-contained and just started.
You mentioned reflection etc. to run the binary. I think it is not that complicated. This is were the last puzzle piece comes into place: environment variables.
There are a bunch of environment variables thar are set by the "runtime". You can find the full list in the AWS documentation: Defined runtime environment variables.
Every Lambda has a environment variable called _HANDLER which points to the handler. In your case this would be the binary. This would allow the runtime to just "run" your handler.
When the handler runs the underlying AWS SDK is starting some kind of webserver/socket (I think it depends on the framework/language) which exposes everything the "standard" runtime needs to communicate with your code.
So as far as I can tell there is not really a dedicated .NET Core runtime. It is pretty generic all the way down, which simplifies development for the folks at AWS I guess.
The source code for Lambda's dotnet runtime(s) is within the aws/aws-lambda-dotnet repository--it doesn't appear to have a dedicated netcoreapp3.1 library, or a preserved branch, but presumably the 3.1 runtime is contained within this repository's history.
The Amazon.Lambda.RuntimeSupport console application appears to be the entrypoint, which in turn instantiates and invokes the published Handler.

What is the proper way to build many Lambda functions and updated them later?

I want to make a bot that makes other bots on Telegram platform. I want to use AWS infrastructure, look like their Lamdba functions are perfect fit, pay for them only when they are active. In my concept, each bot equal to one lambda function, and they all share the same codebase.
At the starting point, I thought to make each new Lambda function programmatically, but this will bring me problems later I think, like need to attach many services programmatically via AWS SDK: Gateway API, DynamoDB. But the main problem, how I will update the codebase for these 1000+ functions later? I think that bash script is a bad idea here.
So, I moved forward and found SAM (AWS Serverless Application Model) and CloudFormatting, which should help me I guess. But I can't understand the concept. I can make a stack with all the required resources, but how will I make new bots from this one stack? Or should I build a template and make new stacks for each new bot programmatically via AWS SDK from this template?
Next, how to update them later? For example, I want to update all bots that have version 1.1 to version 1.2. How I will replace them? Should I make a new stack or can I update older ones? I don't see any options in UI of CloudFormatting or any related methods in AWS SDK for that.
Thanks
But the main problem, how I will update the codebase for these 1000+ functions later?
You don't. You use lambda alias. This allows you to fully decouple your lambda versions from your clients. This works because you are using an alias of your function in your client's code (or api gateway). The alias is fixed and does not change.
However, alias is like a pointer - it can point to different versions of your lambda function. Therefore, when you publish a new lambda version you just point alias to it. Its fully transparent from your clients and their alias does not require any change.
I agree with #Marcin. Also it would be worth checking serverless? Seems like you are still experimenting so most likely you are deploying using bash scripts with AWS SDK/SAM commands. This is fine but once you start getting the gist of what your architecture looks like, I think you will appreciate what serverless can offer. You can deploy/teardown cloudformation stacks in matter of seconds. Also you can use serverless-offline so that you can have a local build of your AWS lambda architecture on your local machine.
All this has saved me hours of grunt work.

How to found supported versions for Amazon SQS?

How to found latest supported version for an AWS service? Not latest.
For example for Amazon SQS?
The current API version for SQS is 2012-11-05, as noted at the top of each page of the SQS API Reference.
Most services list their current API Version this way -- at the top of each page in the API Reference for that service.
The AWS service APIs are usually very stable, so AWS doesn't always bump the version when enhancements come out. That means the date 2012-11-05 for SQS doesn't imply that the API is completely unchanged for 5+ years. Instead, it means that no breaking changes have occurred to the API, and libraries written against any iteration of the 2012-11-05 SQS API will continue to work for all the features that particular library implements, going forward.
There is essentially never a need to specify an older version, nor a need to change the version you reference in any particular project of yours to a newer API version, unless you are trying to use a new feature that is only a available via the newer API release... which generally means your supporting libraries/SDK would need upgrades as well... so once you configure this, there's not often a need to change it.
There is a full list of versions for 3.X services here: https://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html
A managed service, such as Amazon SQS, has one version. There are no lists of supported versions to have to maintain/understand.
Are you talking about different versions of, for example, a java library for SQS?

AWS lambda versioning

I have a question about the lambda functions versioning capabilities.
I know how the standard way of versioning works out of the box in AWS but I thought there is a way for the publisher to specify the version number which would tag a specific snapshot of the function. More exactly what I was thinking of was including in the uploaded zip file a config.json where the version would be specified. And this would be used afterwards by AWS for tagging.
The reason I am asking is because I would like, for example, to keep in sync the version of the lambda function with the CI job build number that built (zipped) the lambda.
Any ideas?
Many thanks
A good option would be store your CI job build number as an environment variable on the Lambda function.
Its not exactly a recommended way to version AWS Lambda functions, but definitely helps in sticking to typical 1.x.x. versioning strategies and keeping them consistent across the pipeline.
Flipping the topic the other way around. Can we go with AWS Lambda versions 1.2.3., and then find a way to have our CI builds also use a single digit version no? Im not yet comfortable with this approach, and like the flexibility of 1.x.x as a versioning scheme to indicate major.minor.patch.
Standard Lambda versioning.
This is the most detailed blog I came across on this topic.
https://www.concurrencylabs.com/blog/configure-your-lambda-function-like-a-champ-sail-smoothly/
When you are deploying the Lambda function through CLI command or API, its not possible to give a custom version number. Its currently an automatically generated value by aws.
This makes it not possible to map the version number in a configuration file to the Lambda version supporting your use case.