Wait, wait, again, “Cloud Management with Serverless Framework” 😎?
That's right, today will be about how you can easily and quickly use the Serverless Framework by elements of the overall orchestration of the AWS platform.
I found such a concept recently in one of the projects, where Serverless Framework was used to build a certain element (NDA) related to management and security.
So I decided to play with it for a while and by the way fire up some small demo to show you how in a few steps you can also do something similar. My example will be a little different, but it's about the concept itself.
Serverless Framework is a tool that allows you to create and deploy solutions and applications based serverless services. In this case, it is primarily about creating solutions based on the Lambda function and everything that functions can interact with.
Surely my fellow developers can tell you more about the benefits of using the Serverless Framework. For the purpose of this entry, you just need to remember that it is one of the tools that allows you to create and deploy serverless applications in a fairly easy way. If you want to bury more, check out serverless.com
Solution example - EC2 instance tagging
So let's look at some simplest example of a solution. Suppose, let them be “again” those immortal virtual machines.
As you know, it's usually one of the more draining portfolio of cloud infrastructure components. Therefore, it is important to run and pay for what is actually used and needed. Especially when we work in a larger team, it is worth taking care to manage appropriately means resources, etc. There is nothing worse than a machine that has no name or a much more eloquent name “do not turn off”.
Thus, in order not to rummage through the logs with CloudTrail, today we will make a simple solution that will add to the machine an additional Tag called Creator, and its value will be replenished with the name of the user who created such a machine.
The solution itself is quite simple, which can be seen in the attached diagram.
Amazon EventBridge provides a definition of the “listening” rule for an event to create a new machine (RunInstance).
The Lambda function is then called, which draws user data and server id for payload.
In the last step, the function tags the machine with the username.
Thus, we will implement the above example using the Serverless Framework.
Installing Serverless Framework
In the first step you need to install yourself a serverless framework. Whether it's on a local computer or Cloud9 or another being, I already leave it to you.
A fabulously simple job just call (I assume you already have node.js installed):
npm install -g serverless
You can find the full documentation HERE
In the next step, you need to provide access to the AWS account where the deployment will be performed. You can use a pair of keys, or aws cli-profiles. More details can be found HERE.
I use a Leapp that logs into AWS and loads temporary cli profiles on my computer.
Having already installed the serverless tool, it's time to prepare the package for deployment.
To do this, I create a working directory, in which I will prepare everything I need. The example is quite simple and contains two files.
The first is the code of my lambda function (taglambda.py), and the second is the configuration file (serverless.yml) based on which the serverless framework will know what to implement.
I will not analyze the function code too much now, I will only deal with what is most important in the serverless.yml file.
We start with the definition of a provider, that is, a cloud platform, in our case it is obviously AWS. In addition, I immediately hammered myself the region in which I will implement my solution (this can also be specified during the deployment). I immediately specify the runtime of my lambda function (python3.7 in this case).
Generally everything that is defined in the provider section is inherited later in the functions that we create further. For example, if I added the MemorySize: 512 configuration, then all functions will have 512MB of memory. Of course, this parameter can be overwritten already in the function definition itself (per function).
By default, a basic IAM role is created for the function, but if I need to grant additional permissions, this is also described in the provider section. My Lambda needs permissions that will allow it to add TAG to the machine.
- Effect: 'Allow'
Resource: 'arn:aws:ec2: *:*: *'
Now I move on to the definition of the function itself.
Functions are created in the functions section, in my case there is only one function so far. Here I specify, among other things, the configuration of handler. The description is quite simple, the first part points to the lambda function file (taglambda.py), and the second is the definition of the function that is called when the lambda is started.
def lambda_handler (event, context):
Here, in addition, I can define additional parameters for this function as the amount of memory, timeout, etc. for the purpose of this demo I will leave it defaultly.
At this point, a deployment of such a configuration could already be performed properly. It is now enough to call a simple command:
All the magic will begin to happen underneath. What will be done is actually the serverless framework will prepare a cloudformation template, which will then deploy to our account.
Event Rule Setup
Of course, so far I have a function, but I do not yet have a configuration related to what will call this lambda.
My solution is used by Amazon EventBridge and rule, which is to catch all the Calle API with the event “RunInstance”, that is, creating a new EC2 machine.
So it's time to configure the event:
- 'AWS API Call via CloudTrail'
To do this, it adds the events section and in it I specify what will “trigger” my lambda function. In this case, it's EventBridge, but you can actually use anything supported by Lambda (Gateway API, SNS, SQS, etc.).
Now having a full setup, it's time to redeploy and test.
Adding Trigger to Lambda function
Now it only remains to run new EC2 instances and check if everything works as it should...
OK, but what about other resources?
Suppose we want our solution to additionally set aside in the DynamoDB table all instances that were created with an additional user description that created them.
We need to create a DynamoDB table (or some other arbitrary AWS resource). In this situation, just add the resources section in the serverless.yml files and in the Cloudformation nomenclature we define the remaining resources.
resources: # CloudFormation template syntax
Type: AWS: :DynamoDB: :Table
- AttributeName: instanceID
As you can see, I was able to implement the following solution quite easily. This is a simple example that I hope will make you curious and encourage you to further explore the possibilities offered by Serverless Framework.
As you can see, I did not touch the elements of multi-account deployment or general automation of the whole process here. It might sometime in some subsequent entry.
However, looking at the same imposes work, it seems quite simple. First of all, you can immediately see that there is less “writing”. At the time of deployment, a cloudformation template is created and here you can immediately check and compare how much longer it will be to what we have here.
If you want to play with this, you can find the solution code on my LINK repository.