Basic Service Example
A complete HTTP API with Lambda functions — from serverless.yml to deployed infrastructure
What you'll build
A simple REST API backed by two Lambda functions: one that lists items and one that creates items. The example shows how sls.tf translates a standard Serverless Framework configuration into Terraform resources.
Project structure
my-api/
modules/
sls.tf/ # git submodule
src/
list.js
create.js
serverless.yml
main.tf
outputs.tf serverless.yml
service: items-api
provider:
name: aws
runtime: nodejs20.x
region: us-east-1
stage: dev
environment:
TABLE_NAME: items-${self:provider.stage}
functions:
listItems:
handler: src/list.handler
description: "List all items"
memorySize: 256
timeout: 10
events:
- http:
path: /items
method: get
cors: true
createItem:
handler: src/create.handler
description: "Create a new item"
memorySize: 256
timeout: 10
events:
- http:
path: /items
method: post
cors: true
resources:
Resources:
ItemsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: items-${self:provider.stage}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH main.tf
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
module "serverless" {
source = "./modules/sls.tf"
config_path = "${path.root}/serverless.yml"
# Grant both functions access to the DynamoDB table
environment_vars = {
STAGE = "dev"
}
} outputs.tf
output "api_url" {
description = "Base URL for the deployed API"
value = module.serverless.api_gateway_invoke_url
}
output "list_items_arn" {
value = module.serverless.function_arns["listItems"]
}
output "create_item_arn" {
value = module.serverless.function_arns["createItem"]
}
output "table_name" {
value = module.serverless.custom_dynamodb_table_names["ItemsTable"]
} Deploy
terraform init
terraform plan
terraform apply
# Output example:
# api_url = "https://abc123.execute-api.us-east-1.amazonaws.com/dev" Test the API
# List items
curl https://abc123.execute-api.us-east-1.amazonaws.com/dev/items
# Create an item
curl -X POST https://abc123.execute-api.us-east-1.amazonaws.com/dev/items \
-H "Content-Type: application/json" \
-d '{"name": "my item"}' What sls.tf created
- Two
aws_lambda_functionresources (listItems,createItem) - Two
aws_iam_roleexecution roles with CloudWatch Logs permissions - One
aws_api_gateway_rest_apiwith routes forGET /itemsandPOST /items - CORS configuration on both routes
- One
aws_dynamodb_tablefrom theresources:block - Lambda permissions for API Gateway to invoke each function
Next steps
- TypeScript Config Example — the same service in TypeScript
- Outputs Reference — all available outputs
- Configuration Guide — advanced options