We will cover briefly:
- Options for deploying lambda
- Setup serverless
- Create lambda (upload image to s3 bucket) using serverless
- Deploy lambda using serverless
Options for deploying lambda
As of writing this article, there are two ways of deploying lambdas onto AWS
The AWS Serverless Application Model (AWS SAM) is an open-source framework that you can use to build serverless applications on AWS
One of the key benefits of SAM is Local debugging and testing
It lets you locally build, test, and debug serverless applications that are defined by AWS SAM templates. which helps you catch issues upfront by providing parity with the actual Lambda execution environment
Develop, deploy, troubleshoot, and secure your serverless applications with radically less overhead and cost by using the Serverless Framework. The Serverless Framework consists of an open-source CLI.
Serverless allows us to focus on the code, while it takes care of the setting up policies, and provisioning of required infrastructure onto AWS
Setup serverless
To install serverless
, follow here. Personally, I configured using the below
npm install -g serverless
- Once installed you can access it by typing
sls
on your terminal - We now have access to multiple templates by this command
sls create --help
We will focus on the Go specific one, which is aws-go-dep
Let's use this template to create a simple lambda. The final command for that is
sls create --template aws-go-dep --path upload-s3
--template
is used to specify the template name
--path
(Optional) is used to specify the directory in which your code is to be placed
- We should see a folder structure like this
- By default, the
aws-go-dep
a template gives us twohttp (GET)
based endpoints, which can be seen in theserverless.yml
functions:
hello:
handler: bin/hello
events:
- httpApi:
path: /hello
method: get
world:
handler: bin/world
events:
- httpApi:
path: /world
method: get
The equivalent files correspond to hello/main.go
and world/main.go
- In case you see errors, try to run the following commands
go mod init <SOME NAME HERE>
go mod tidy
This will help in setting the go.mod
which is required for any go program
Create lambda (upload image to s3 bucket) using serverless
We will modify our lambda to upload an image to an S3 bucket.
- We delete the unnecessary endpoints from the
serverless.yml
and unwanted folders likehello/main.go
andworld/main.go
- Create a new folder called
upload
and inside it creates a filemain.go
- We will define a request body struct that will accept
filename
and thebody
as input. (Note: the body would be the base64 encoder of an image)
For getting the base64 of any image, check here
type ImageRequestBody struct {
FileName string `json:"filename"`
Body string `json:"body"`
}
We will parse the body from the input and decode it using DecodeString
which returns the bytes represented by the base64 string
decoded, err := base64.StdEncoding.DecodeString(bodyRequest.Body)
All our image-related functions are inside img_utils.go. After decoding the image into bytes from the previous step, we now take those bytes and form a temporary file
func imageUpload(data []byte) {
tmpFileName := fmt.Sprintf(`/tmp/%s`, bodyRequest.FileName)
fileErr := ioutil.WriteFile(tmpFileName, []byte(data), 0644)
// CALL THE UPLOAD FUNCTION
UploadImage(tmpFileName)
}
In the first line, we are specifying the file at a location tmp
. This is an important step and as per AWS documentation
The Lambda execution environment provides a file system for your code to use at /tmp. This space has a fixed size of 512 MB. Each time a new execution environment is created, this area is deleted.
Next, we write the file with the bytes using WriteFile
WriteFile writes data to a file named by filename. If the file does not exist, WriteFile creates it with permissions perm (before umask); otherwise WriteFile truncates it before writing, without changing permissions.
So now we have our temporary file created!
- Now we will upload the file, onto the AWS S3 bucket. For that, we will be using the AWS GO SDK and in case you don’t have it installed follow this
go get github.com/aws/aws-sdk-go
We will pass our file to the upload function
func uploadToS3Bucket(file io.Reader, fileName string) {
bucketName := os.Getenv("bucket_name")
region := "us-east-2"
conf := aws.Config{Region: ®ion}
sess, _ := session.NewSession(&conf)
uploader := s3manager.NewUploader(sess)
upParams := &s3manager.UploadInput{
Bucket: &bucketName,
Key: &fileName,
Body: file,
}
result, err := uploader.Upload(upParams)
}
- We need to specify the region using
aws.Config
. In our case it was us-east-2.
- We need to specify the region using
aws.Config
. In our case it was us-east-2.
session.Newsession
returns a new Session created from SDK defaults, config files, environment, and user-provided config files.
aws-sdk-go
gives us s3Manager
which helps in uploading the file. It takes in
Bucket
: Your AWS bucket name, in my case I get from serverless.yml
environment variable
Key
: Object key for which the PUT action was initiated. In our case, it's the filename.
Body
: What is the body payload to send to S3. In our case, it's the file itself
- Finally, using the above parameters, we call the
Uploader.Upload
- We return the response from the
main.go
back to the caller
Deploy lambda using serverless
Till now we were creating our lambda, but now it's time to deploy it onto AWS.
- Let’s revisit our
serverless.yml
and make some changes
functions:
upload:
handler: bin/upload
events:
- httpApi:
path: /uploadImage
method: post
We add in the post endpoint uploadImage
for our lambda
- Next, since we are using the S3 bucket from inside lambda, we will add some IAMRoleStatements
custom:
s3Bucket: test-bucket--aseem
iamRoleStatements:
- Effect: Allow
Action:
- s3:*
Resource: "arn:aws:s3:::${self:custom.s3Bucket}/*"
This specifies the bucket name using s3Bucket
and allows executing the operations on this bucket
- Finally, for specifying the environment variables, we make use of
environment:
bucket_name: test-bucket--aseem
We will create a Makefile
and put the following
deploy: clean build
sls deploy --verbose
remove:
sls remove
This will help in easing the lambda deployment, by simply calling
make deploy
If everything was successful, you should see something like this
For removing the lambda, we can call
make remove
For testing the lambda, use the
curl -X POST -H "Content-Type: application/json" \
-d '{"filename": "xyz.png", "body": "BASE_64_ENCODING_OF_AN_IMAGE"}' \
<YOUR_LAMBDA_URL>
Top comments (0)