# Deploying AWS Lambda in GoLang with Serverless framework


## What is AWS Lambda?

AWS Lambda is a serverless computing service provided by Amazon Web Services (AWS)
AWS Lambda lets you run code without provisioning or managing servers. 

![lambda](https://cdn.hashnode.com/res/hashnode/image/upload/v1670398002254/M52_ErmYF.png align="center")

## How does this work?
You may think, how you make your code work without provisioning a server. Well, you write Lambda functions in one of the languages and runtime supported by AWS lambda.
Your code is uploaded to AWS lambda which runs your code only when needed and scales automatically.
Not having to provision or manage a server and still having your code run is what makes this a part of the Serverless architecture. 

### Are there no servers involved?
No, the concept of serverless means not needed to maintain **your own** server.
AWS Lambda service takes care of the servers, the operating systems, the network layer and the rest of the infrastructure, so you just need to focus on writing application code.

### What does "run your code only when needed" mean?
Your lambda function runs the code when it is triggered by an event. 
Some common ways to trigger your lambda function are :
- API Gateway
- S3
- DynamoDB Table Streams

## Let's code
The best way to learn is to implement.
## What are we building?
We are going to make a simple lambda function in golang. Every developer's favourite: Hello world :)

## Pre-Requisites
- Basic knowledge of golang
- Basic understanding of handlers

## Project setup

From the local machine, create a directory named aws-lambda and change the directory to it.

`mkdir aws-lambda-go && cd aws-lambda-go`

Initialize the Go project with a module file.

`go mod init`

The next part in writing the code in main.go


    func hello() (events.APIGatewayProxyResponse, error) {
        body := "Hello World"
	    
        return events.APIGatewayProxyResponse{
		    StatusCode: 200,
		    Body:       body,
	    }, nil
    }


We have created a handler named hello which returns "Hello World".
One thing to note is, this handler returns events.APIGatewayProxyResponse
This is because we will be using AWS API Gateway to trigger our lambda and AWS API Gateway expects a response in the mentioned format.
It contains our StatusCode which will be 200 for the successful response and our Body which is the ```"Hello World"``` string.

To add the dependencies use the following commands:

`go get github.com/aws/aws-lambda-go/lambda`

`go get github.com/aws/aws-lambda-go/events`

Our main function calls the handler with Lambda.Start function.
Here is how are main.go looks:


    package main

    import (
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    )

    func hello() (events.APIGatewayProxyResponse, error) {
        body := "Hello World"

	    return events.APIGatewayProxyResponse{
		    StatusCode: 200,
		    Body:       body,
	    }, nil
    }
    func main() {
    lambda.Start(hello)
    }

### Creating the executable file and zip file
Use the following command to build your executable file

    GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o bootstrap cmd/main.go

Now zip the executable file

    zip -9 -j bootstrap.zip bootstrap


The next section covers how we deploy our lambda function.

## Serverless Framework
The Serverless Framework is a command-line tool that uses YAML syntax to deploy both your code and cloud infrastructure needed. It supports Node.js, Typescript, Python, Go, Java, and more.

![serverless](https://cdn.hashnode.com/res/hashnode/image/upload/v1670398069000/cBX3rjmex.png align="center")
## Advantages of serverless framework

- Cost: You pay only for what you use. There is no need to reserve extra space for your services.
- Flexibility: Instances are automatically scaled.
- Accuracy and Speed: Developers can simply deploy their code without having to manage any servers, which helps accelerate delivery cycles and rapidly scale company operations.

## Challenges of serverless framework
- Loss of Control: You’re dependent on a cloud provider for functioning of servers
- Security: If the shared server isn’t configured properly, your application data could be exposed.
- Testing: Developers can run unit tests on function code, but integration tests, which evaluate how frontend and backend components interact, are difficult to perform in a serverless environment.
- Performance Impact: Cold starts are common in serverless environments, adding several seconds of latency to code execution when functions are invoked after a period of inactivity.
- Complexity: If something isn't working as it should, spotting the issue could be difficult. You'll have multiple spaces in which to look.


## Serverless Architecture Use Cases

- Trigger-based tasks: Trigger-based or event-driven tasks are commonly used with serverless framework.

- Building RESTful APIs
You can build RESTful APIs using Amazon API Gateway with serverless functions with high scalability.

- Security checks
When you spin up a new container, a function can be invoked to scan the instance for misconfigurations or vulnerabilities. Functions can also be used as a more secure option for SSH verification and two-factor authentication.

- Continuous Integration (CI) and Continuous Delivery (CD)
Serverless architectures can automate many of the stages in your CI/CD pipelines. For example, code commits can trigger a function to create a build, and pull requests can trigger automated tests.

## Install serverless

Set up a new npm package with the following command:

    npm init

You will see the following, enter the details as per your wish.

![npm init](https://cdn.hashnode.com/res/hashnode/image/upload/v1670398109384/agIRSoaz7.png align="center")

Install the serverless CLI via NPM:

    npm install -g serverless

## Getting started with serverless

The following command will guide you to create a new serverless project

    serverless

Moving ahead we will be using the alias "sls" for the serverless commands

Configure your aws credentials

    sls config credentials --provider aws --key <aws access key> --secret <aws secret key>

( You need to create an AWS IAM user and access key first if you don't have one already )

### The serverless YAML file

    service: aws-lambda-1

    provider:
        name: aws
        runtime: go1.x
        region: ap-south-1

    functions:
        blogExample:
        handler: bootstrap
        events:
         - http:
            method: get
            path: blogExample
            cors:
                origin: "*"
                headers: "*"
        package:
            individually: true
            artifact: bootstrap.zip

### Let us understand the yaml file
- Declare the name of your service

`service: aws-lambda-1`

- Configure the provider you are using : Here we are using aws with runtime go1.x as we have written our code in Go.

```
provider:
    name: aws
    runtime: go1.x
    region: ap-south-1
```

- Declare the functions : We have named our function "blogExample", the handler is the executable file which will run your code when this function is invoked. 

```
functions:
    blogExample:
    handler: bootstrap
```

- Events is what can trigger our function. We will be using an http event, The path to our function will be blogExample. Configure the cors settings.
```
events:
    -http:
    method: get
    path: blogExample
    cors:
        origin: "*"
        headers: "*"
```

- Configuration for your package, here we have a zip file named bootstrap.zip which we will be uploading to our lambda function. The individually ture property enables you to package your functions individually.

```
package:
    individually: true
    artifact: bootstrap.zip
```
- We named our file bootstrap because if there's a file named bootstrap in your deployment package, Lambda runs that file. If not, Lambda looks for a runtime in the function's layers. If the bootstrap file isn't found or isn't executable, your function returns an error upon invocation. So, using bootstrap file is a safe and general practice.



### Deploy your service
    
    sls deploy

- You should see the following output with your function url:

![deploy output](https://cdn.hashnode.com/res/hashnode/image/upload/v1670401001396/oV4zTI03C.png align="center")

- You can see your function on the AWS Lambda dashboard

![dashboard output](https://cdn.hashnode.com/res/hashnode/image/upload/v1670404141632/osiULDURa.png align="left")

We have successfully deployed our lambda function, the serverless deploy takes care creating the required AWS stack.

Hope this blog was helpful in understanding AWS Lambda and the serverless framework.
