Serverless computing is a cloud computing model in which a cloud provider allocates compute resources on demand. This contrasts with traditional cloud computing where the user is responsible for directly managing virtual servers.
Most serverless applications use Functions as a Service (FaaS) to provide application logic, along with specialized services for additional capabilities such as routing HTTP requests, message queuing, and data storage.
In this tutorial, you will deploy a NodeJS function to AWS Lambda, and then expose that function to the Internet using Amazon API Gateway.
»Prerequisites
This tutorial assumes that you are familiar with the standard Terraform workflow. If you are new to Terraform, complete the Get Started tutorials first.
For this tutorial, you will need:
- The Terraform CLI (1.0.1+) installed.
- An AWS account.
- The AWS CLI (2.0+) installed, and configured for your AWS account.
Warning: Some of the infrastructure in this tutorial does not qualify for the AWS free tier. Destroy the infrastructure at the end of the guide to avoid unnecessary charges. We are not responsible for any charges that you incur.
»Clone example configuration
Clone the Learn Terraform Lambda and API
Gateway GitHub
repository for this tutorial. If you're stuck at any point during this tutorial, refer to the final
branch to find the final configuration.
Change to the repository directory.
Review the configuration in main.tf
. It defines the AWS provider you will use
for this tutorial and an S3 bucket which will store your Lambda function.
Initialize this configuration.
Apply the configuration to create your S3 bucket. Respond to the confirmation
prompt with a yes
.
»Create and upload Lambda function archive
To deploy an AWS Lambda function, you must package it in an archive containing the function source code and any dependencies.
The way you build the function code and dependencies will depend on the language and frameworks you choose. In this tutorial, you will deploy the NodeJS function defined in the Git repository you cloned earlier.
Review the function code in hello-world/hello.js
.
This function takes an incoming event object from Lambda and logs it to the console. Then it returns an object which API Gateway will use to generate an HTTP response.
Add the following configuration to main.tf
to package and copy this function to your S3 bucket.
This configuration uses the archive_file
data
source
to generate a zip archive and an aws_s3_object
resource
to upload the archive to your S3 bucket.
Create the bucket object now. Respond to the confirmation prompt with a yes
.
Once Terraform deploys your function to S3, use the AWS CLI to inspect the contents of the S3 bucket.
»Create the Lambda function
Add the following to main.tf
to define your Lambda function and related
resources.
This configuration defines four resources:
aws_lambda_function.hello_world
configures the Lambda function to use the bucket object containing your function code. It also sets the runtime to NodeJS 12.x, and assigns the handler to thehandler
function defined inhello.js
. Thesource_code_hash
attribute will change whenever you update the code contained in the archive, which lets Lambda know that there is a new version of your code available. Finally, the resource specifies a role which grants the function permission to access AWS services and resources in your account.aws_cloudwatch_log_group.hello_world
defines a log group to store log messages from your Lambda function for 30 days. By convention, Lambda stores logs in a group with the name/aws/lambda/<Function Name>
.aws_iam_role.lambda_exec
defines an IAM role that allows Lambda to access resources in your AWS account.aws_iam_role_policy_attachment.lambda_policy
attaches a policy the IAM role. TheAWSLambdaBasicExecutionRole
is an AWS managed policy that allows your Lambda function to write to CloudWatch logs.
Add the following to outputs.tf
to create an output value for your Lambda function's name.
Apply this configuration to create your Lambda function and associated
resources. Respond to the confirmation prompt with a yes
.
Once Terraform creates the function, invoke it using the AWS CLI.
Check the contents of response.json
to confirm that the function is working as
expected.
This response matches the object returned by the handler function in
hello-world/hello.js
.
You can review your function in the AWS Lambda Console.
»Create an HTTP API with API Gateway
API Gateway is an AWS managed service that allows you to create and manage HTTP or WebSocket APIs. It supports integration with AWS Lambda functions, allowing you to implement an HTTP API using Lambda functions to handle and respond to HTTP requests.
Add the following to main.tf
to configure an API Gateway.
This configuration defines four API Gateway resources, and two supplemental resources:
aws_apigatewayv2_api.lambda
defines a name for the API Gateway and sets its protocol toHTTP
.aws_apigatewayv2_stage.lambda
sets up application stages for the API Gateway - such as "Test", "Staging", and "Production". The example configuration defines a single stage, with access logging enabled.aws_apigatewayv2_integration.hello_world
configures the API Gateway to use your Lambda function.aws_apigatewayv2_route.hello_world
maps an HTTP request to a target, in this case your Lambda function. In the example configuration, theroute_key
matches any GET request matching the path/hello
. Atarget
matchingintegrations/<ID>
maps to a Lambda integration with the given ID.aws_cloudwatch_log_group.api_gw
defines a log group to store access logs for theaws_apigatewayv2_stage.lambda
API Gateway stage.aws_lambda_permission.api_gw
gives API Gateway permission to invoke your Lambda function.
The API Gateway stage will publish your API to a URL managed by AWS.
Add an output value for this URL to outputs.tf
.
Apply your configuration to create the API Gateway and other resources. Respond
to the confirmation prompt with a yes
.
Now, send a request to API Gateway to invoke the Lambda function. The endpoint consists of the
base_url
output value and the /hello
path, which do you defined as the route_key
.
»Update your Lambda function
When you call Lambda functions via API Gateway's proxy integration, API Gateway
passes the request information to your function via the event
object. You can
use information about the request in your function code.
Now, use an HTTP query parameter in your function.
In hello-world/hello.js
, add an if
statement to replace the
responseMessage
if the request includes a Name
query parameter.
Apply this change now.
Since your source code changed, the computed etag
and source_code_hash
values have changed as well. Terraform will update your S3 bucket object and
Lambda function.
Respond to the confirmation prompt with a yes
.
Now, send another request to your function, including the Name
query parameter.
Before cleaning up your infrastructure, you can visit the AWS Lambda Console for your function to review the infrastructure you created in this tutorial.
»Clean up your infrastructure
You have created an AWS Lambda function with an API Gateway integration. These components are essential parts of most serverless applications.
Before moving on, clean up the infrastructure you created by running the
terraform destroy
command.
Remember to confirm your destroy with a yes
.
»Next steps
Now that you have learned how to deploy Lambda functions with Terraform, check out the following resources for more information.
The Terraform Registry includes modules for Lambda and API Gateway, which support serverless development.
Create and use Terraform modules to organize your configuration.
Use the Cloud Development Kit (CDK) for Terraform to deploy multiple Lambda functions with TypeScript.