Getting Started with the Serverless framework on AWS

I have been in hibernation for some time as I shifted jobs, moved houses and have been hellishly busy, so, my bad that I haven’t written an article in a while.

In this article, I am going to introduce and help you get started with the serverless tool where we are going to create a AWS Lambda function in .NET core, make Dynamo DB tables that it would use all without leaving Visual Studio Code.

In case you are new to either Visual Studio Code which is a cross-platform open source IDE for a number of languages or new to AWS Lambda you can read my getting started guide on that first.
It is also worth reading AWS Lambda’s best practices and a guide to how it works internally in this article of mine.

What is the Serverless Framework?

Serverless architecture is basically a design which does not use any physical server or VM or Containers of any sort (at least not directly) with the realization that those are difficult to manage, harder to scale, tougher to get talent for and most importantly puts our time in something which is not catering to the business that we are targeting.

On AWS, Lambda is the service on which you would upload your code and AWS will allocate infrastructure in response to whatever event you configure it to listen to. I am going to assume that you know how it works, if you don’t read the article I mentioned before first.

To understand what is the Serverless framework, you must know what is Cloud formation as well. Cloud formation is a tool through which you can design templates in either YAML or JSON and once ‘executed’ will launch AWS resources (VPC’s, EC2’s, Cache servers, DB’s, whatever) for you. If the Cloud Formation ‘stack’ existed previously it will compute the changes and do edit only, you can even tear everything down using it cleanly and simply.

Wow, I still don’t know what is Serverless Framework after all that talk

It was necessary to give that much of a detailed background. Now.. the Serverless framework is a very elaborate ‘tool’ using which developers can build and design the entire infrastructure that your code would need without leaving your favourite IDE.

An example Serverless template:

service: tokenGenerator
package:
    artifact: publish.zip
provider:
  name: aws
  runtime: dotnetcore1.0
  stage: ${opt:stage} #read from console input
  region: us-west-2
  profile: personal #this is the AWS credentials profile, change this.. or pass AWS credentials in the command line (not recommended)
  role: arn:aws:iam::<myAWSAccId>:role/serverless_getting_started
  memorySize: 128 # Overwrite the default memory size. Default is 1024
  timeout: 100 #default is 6
  #deploymentBucket: myBucketName.${self:provider.region}.deploys #I recommend leave this commented out, serverless will create a bucket for you if this is not given
  versionFunctions: false
  stackTags:
   Environment: ${opt:stage} #helpful for billing
  stackPolicy: # Optional CF stack policy. The example below allows updates to all resources except deleting/replacing EC2 instances (use with caution!)
    - Effect: Allow
      Principal: "*"
      Action: "Update:*"
      Resource: "*"
    - Effect: Deny
      Principal: "*"
      Action:
        - Update:Replace
        - Update:Delete
      Condition:
        StringEquals:
          ResourceType:
            - AWS::EC2::Instance

functions:
  echoGenerator:
    name: ${opt:stage}echoGenerator
    handler: Serverless_Getting_Started::Serverless.Getting.Started.LambdaEntryPoint::FunctionHandlerAsync
    events:
      - http:
          path: echo
          method: get

# The "Resources" your "Functions" use.  Raw AWS CloudFormation goes in here.
resources:
  Resources:
    usersTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${opt:stage}Users
        AttributeDefinitions:
          - AttributeName: Id
            AttributeType: S
        KeySchema:
          - AttributeName: Id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

The template above will do the following:

  1. Create an S3 bucket to upload your code if one does not exist.
  2. Upload the function code, publish.zip in this case as I specified it.
  3. Create the Lambda function with the config I defined in the YAML.
  4. Create a CloudWatch log group to which your Lambda will write logs to.
  5. Create an API gateway which accepts http GET requests and passes it onto the Lambda code.
  6. Creates a DynamoDB function.
  7. If any of the above exists, it will update it according to the config in the YAML, this is useful to push updates like increasing DynamoDB throughputs or creating indexes on them etc.
  8. It will clean anything that was created previously and removed from the YAML.

And the command to do all that?

serverless deploy --stage blog --region us-west-2

Nice, isn’t it? Notice that I wrote stage name as ‘blog’, you can replace that with dev, qa, performance etc and different environments are up just like that!

Nice! Lets see the code

Download the code from here: https://github.com/maingi4/Serverless_Getting_Started

Create a role for your Lambda function

This is needed by your Lambda function in order to have the necessary permissions to put logs in cloudwatch, query DynamoDB etc. Simply follow the images.

Step 1: Select the role type AWS Lambda
Create a role step 1

Step 2: Put dynamo in the search box and select the AWSLambdaDynamoDBExecutionRole
Create a role step 2

Step 3: Set a role name and save
Create a role step 3

Setting up serverless

Make sure you have node.js installed, if not get it from here.

Install serverless which comes as a npm package with the following command:
npm install serverless -g
The above command installs serverless globally.

Make sure you have .NET core installed according to your platform, get it from here.

Open the downloaded code in Visual Studio Code or Visual Studio.

Open the serverless.yml file and replace the role arn with the one you created before, you can take this opportunity to change the region to one of your choice as well, make sure you change the region in subsequent commands as well. Also change the profile section to include your own AWS profile stored in your machine, serverless will use those credentials to do a lot of stuff.

Run the build.bat file that I have included, its for windows only, so I’ll give a breakdown of what it does in case you are on MAC or something:

Runs the restore command to get all the required nuget packages:
dotnet restore

Build and publishes the library to a folder out in the root directory:
dotnet publish -c Release -o out

Creates a zip (deletes one if it already exists) with the contents of the out folder, make sure that only the contents are zipped, basically when you open the zip file you should see the dll files etc and NOT the out folder, this is important for your Lambda function to be able to run:

SET PublishFile="publish.zip"
IF EXIST %PublishFile% del /F %PublishFile%
powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::CreateFromDirectory('out', '%PublishFile%'); }"

If you are on MAC or Linux, use your favourite command line tool to zip stuff up, on Linux my favourite is the zip utility apt-get -y install zip

The file publish.zip is mentioned in the serverless.yml file, so make sure the name matches.

Run the serverless deploy command:
serverless deploy --stage blog --region us-west-2 --verbose

That’s it, you now have a ‘blog’ environment!

To see the service in action call your service URL, you can find the URL in the output of your serverless deploy command, like in the image (at the bottom of it):
serverless deploy command in action

My output looks like this:
enter image description here

In case you get a error saying internal server error, make sure the API gateway has permission to invoke Lambda, do this by going to the API gateway in the AWS console>>Resources(left pane)>>GET(middle pane)>>Integration Request(right pane) and edit the Lambda function name and without changing it, just save it. A dialog box will ask you whether you want to give API gateway permission to invoke the Lambda function. This is an issue with serverless deployments, I usually solve it by command line using AWS-CLI but I didn’t wanted to pollute the blog with all that.

Mind you we created a Dynamo DB table just to prove a point but didn’t actually use it, when you are done playing around you can tear everything down by running the following serverless command:

serverless remove --stage blog --region us-west-2 --verbose

Everything that serverless created will now be removed.

Now that I have had fun creating and destroying environments a few dozen times, isn’t this dangerous?

In the real world with a team in place, you don’t want to have developers creating and destroying environments at will of course. My AWS role in my machine to my personal AWS account has all the priviliges in the world, hence serverless could do all that. However, since not everybody will have these priviliges, you will be doing this via a CI tool like Jenkins or AWS CodeBuild.

In the interest of going serverless, I recently switched over to AWS CodeBuild and will probably write a blog post about it in the near future.

If you liked this article, you can choose to follow this blog/subscribe to email alerts (top of sidebar or below comments in mobile) so that you know when any future posts come about.

Advertisements

7 thoughts on “Getting Started with the Serverless framework on AWS

  1. Pingback: Getting Started with the Serverless framework on AWS | Ace Infoway

  2. In the Azure realm, I recently implemented Azure Functions for data massaging and dumping mined results for faster reporting, ultimately presented with Power BI UI tools. Very neat. Yet, those who coined the “serverless” term, should be hanged for misleading nomenclature.

    Liked by 1 person

  3. Sumit,
    Is there a way to work with an RDS (SQL Server) via entity framework with a Serverless application ? Is this supported to begin with. I tried installing the entity framework Nuget but it failed with an error. Appreciate your insights..

    Like

    • AWS lambda supports .Net core through which u can use RDS, check out an article that I had written on getting started with AWS Lambda with .net core, I am travelling otherwise I would have posted the link directly.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s