AWS CLI Lambda Function

AWS CLI Lambda Function

In this tutorial we will learn how to use the AWS cli to deploy a serverless node.js application using AWS Lambda and AWS API Gateway.

Before we get started, I want to be honest with you. This may not be the most ideal way of doing things, but it's always helpful to understand the basics before diving into more advanced tools like terraform, serverless framework, SAM, AWS CDK, and others.

Don't worry, I'll be covering some of those tools in future tutorials, but for now, let's enjoy the learning experience and appreciate the fundamentals of deploying a serverless application with AWS CLI.

AWS CLI

AWS CLI is a command line tool that allows you to interact with AWS services from, you guessed it, the command line. It's a great tool to have in your arsenal, and setting it up is usually the first step before using any infrastructure as code tool. If you haven't already, follow my tutorial on how to install and configure the AWS CLI.

Node.js Lambda Function

We'll start by creating a basic node function that just returns a "Hello World" message. Then we'll create a new lambda function in AWS and deploy our code.

👩🏻‍💻Follow these steps to create a new node.js function:
  1. Create a new directory for your function and navigate to it in the terminal.

  2. Initialize your function with npm init and follow the prompts to create a new package.json file.

  3. Add "type": "module" to the package.json file to enable ES6 modules.

  4. Create a new file called index.js and add the following code:

    export const handler = async (event) => {
      return {
        statusCode: 200,
        body: "Hello World!",
      };
    };
    
👩🏻‍💻Zip your function code into function.zip by running the following command:
zip -r function.zip index.js package.json

Note

When you have dependencies, you'll need to zip them as well. You can do this by running the following command:

zip -r function.zip index.js package.json node_modules/

Create a Lambda Function

Before we can create a new Lambda function on AWS, we need to create an IAM role for the Lambda function. This role will grant the Lambda function permissions to access whichever AWS resources it needs. For now it will just need the AWSLambdaBasicExecutionRole policy, which grants the function basic permissions to access CloudWatch.

👩🏻‍💻Run the following command to create the IAM role:
aws iam create-role \
--role-name MyFunctionName_Role \
--assume-role-policy-document '{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "lambda.amazonaws.com"},"Action": "sts:AssumeRole"}]}'
👩🏻‍💻Attach the AWSLambdaBasicExecutionRole policy to the role by running the following command:
aws iam attach-role-policy \
--role-name MyFunctionName_Role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

Make a note of what the role ARN is.

👩🏻‍💻Create a new lambda function:
aws lambda create-function \
--function-name MyFunctionName \
--runtime nodejs18.x \
--role <arn> \
--handler index.handler \
--zip-file fileb://function.zip
👩🏻‍💻Replace <arn> the the arn of the IAM role you created earlier.

Make a note of the FunctionArn that is returned. You'll need this later. And that's it! You've now created a new Lambda function with your JS code.

Re Deploying Code

Every time you make an update to your code you'll need to redeploy it to AWS. You can do this by running the following command:

👩🏻‍💻Zip your function code and dependencies by running the following command:
zip -r function.zip index.js package.json node_modules/
👩🏻‍💻Update the lambda function with the new code:
aws lambda update-function-code \
--function-name MyFunctionName \
--zip-file fileb://function.zip

Deleting a Lambda Function

And when you're done with your function, you can delete it by running the following command:

aws lambda delete-function \
--function-name MyFunctionName

API Gateway

Of course, we don't want to have to call our Lambda function directly. We want to be able to call it from the web. To do this, we'll use API Gateway. But before we can do that, we need our function's ARN.

👩🏻‍💻Get the ARN of your Lambda function by running the following command:
aws lambda get-function --function-name MyFunctionName

To create a new HTTP API Gateway for the Lambda function, we can use the create-api and create-resource commands.

👩🏻‍💻Run the following command to create a new HTTP API:
aws apigatewayv2 create-api \
--name MyHTTPAPI \
--protocol-type HTTP 

Make a note of the API id.

👩🏻‍💻Create a new auto deployment for API gateway by running the following command:
aws apigatewayv2 create-stage \
--api-id <ApiId> \
--stage-name dev \
--auto-deploy

Replace ApiId with the id of the API you just created.

Now whenever we make a change, like adding a new lambda function to the gateway, the changes will get automatically deployed.

👩🏻‍💻Add the lambda function to the API gateway by running the following command:
aws apigatewayv2 create-integration \
    --api-id <ApiId> \
    --integration-type AWS_PROXY \
    --integration-uri <FunctionArn> \
    --payload-format-version 2.0

Make a note of the IntegrationId that is returned.

👩🏻‍💻Create a new route for the API gateway by running the following command:
aws apigatewayv2 create-route \
--api-id <ApiId> \
--route-key "GET /test" \
--target integrations/<IntegrationId>

We're almost there, we just need to give API gateway permission to invoke the function. But in order to do that, you need your aws profile id which you can find by running the following command:

aws sts get-caller-identity --query "Account" --output text
👩🏻‍💻Add permission to the lambda function by running the following command:
  aws lambda add-permission \
  --function-name <FunctionARN> \
  --statement-id <UUID> \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn <API_GATEWAY_ARN> 

The ARN of the HTTP API Gateway should be in the format arn:aws:execute-api:<REGION>:<ACCOUNT_ID>:<API_ID>/*.

Once all of these steps have been succesfully completed, you should be able to visit your API gateway in the browser.

👩🏻‍💻Find the url by running the following command:
aws apigatewayv2 get-api \
  --api-id <ApiId>

Delete API gateway

When you're ready to delete your api gateway, you can do so with this command:

aws apigatewayv2 delete-api --api-id <API_ID>

Find an issue with this page? Fix it on GitHub