A simple demonstration project that triggers an AWS Lambda function written in Go via API Gateway proxy integration, using LocalStack for local development and testing.
This project demonstrates:
- Go Lambda Function: A simple AWS Lambda handler that responds to API Gateway requests
- API Gateway Integration: AWS API Gateway configured with proxy integration to invoke the Lambda
- LocalStack: Complete local AWS environment for development and testing
- Infrastructure as Code: Terraform configuration for deploying all AWS resources
- Automated Build: Makefile with commands to build, deploy, and test the entire stack
API Gateway (REST API)
└── /{proxy+} endpoint
└── POST method
└── AWS_PROXY integration
└── Lambda Function (Go)
└── Returns "Hello from Lambda!"
- Docker and Docker Compose
- Go (1.x or later)
- Terraform
- tflocal - Terraform wrapper for LocalStack
- awslocal - AWS CLI wrapper for LocalStack (optional)
- LocalStack Pro license (configured in
.envfile)
.
├── src/
│ └── lambda/
│ ├── main.go # Lambda function handler
│ ├── go.mod
│ └── go.sum
├── terraform/
│ ├── main.tf # Main Terraform configuration
│ ├── api_gateway.tf # API Gateway and Lambda resources
│ └── bootstrap.zip # Built Lambda deployment package (generated)
├── docker-compose.yml # LocalStack container configuration
├── makefile # Build and deployment automation
└── readme.md
Create a .env file in the project root with your LocalStack Pro API key:
LOCALSTACK_API_KEY=your-api-key-here
Run the complete initialization process:
make initThis will:
- Start LocalStack in a Docker container
- Build the Go Lambda function and create a deployment package
- Deploy the infrastructure using Terraform
Invoke the API Gateway endpoint to trigger your Lambda:
make invokeYou should receive a response:
Hello from Lambda!
| Command | Description |
|---|---|
make init |
Complete setup: starts LocalStack, builds Lambda, deploys infrastructure |
make localstack |
Start LocalStack container |
make build |
Build Go Lambda function and create deployment zip |
make terraform |
Deploy infrastructure with Terraform |
make invoke |
Test the API Gateway endpoint |
make clean |
Remove build artifacts and Terraform state |
make shutdown |
Clean up and stop LocalStack container |
If you prefer to test manually, you can use curl directly:
# Get your API Gateway ID
API_ID=$(tflocal -chdir=terraform output -raw api_gateway_id)
# Invoke the endpoint
curl -X POST http://localhost:4566/restapis/$API_ID/v1/_user_request_/testOr test with a payload:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"message": "Hello"}' \
http://localhost:4566/restapis/$API_ID/v1/_user_request_/anythingThe Lambda function (src/lambda/main.go) is a simple handler that:
- Accepts API Gateway proxy requests
- Returns a 200 status code
- Responds with "Hello from Lambda!"
func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
response := events.APIGatewayProxyResponse{
StatusCode: 200,
Headers: map[string]string{
"Content-Type": "text/plain",
},
Body: "Hello from Lambda!",
}
return response, nil
}The Terraform configuration deploys:
- API Gateway REST API with a catch-all
{proxy+}resource - Lambda Function using Go custom runtime (
provided.al2) - API Gateway Integration configured for AWS_PROXY
- Lambda Permissions allowing API Gateway to invoke the function
- API Gateway Stage (v1) for accessing the API
- Edit
src/lambda/main.go - Rebuild and redeploy:
make build make terraform
tflocal -chdir=terraform outputEnable verbose output in the makefile by removing the @ prefix from commands, or use curl with -v flag:
curl -v -X POST http://localhost:4566/restapis/$API_ID/v1/_user_request_/test- Check Docker is running
- Verify
.envfile contains validLOCALSTACK_API_KEY - Check logs:
docker-compose logs -f
- Verify the Lambda was deployed:
awslocal lambda list-functions - Check Lambda logs in LocalStack
- Ensure API Gateway has permission to invoke Lambda
- Verify the API Gateway ID:
tflocal -chdir=terraform output api_gateway_id - Check the stage name is correct (v1)
- Use the
_user_request_path segment for LocalStack
Stop LocalStack and remove all artifacts:
make shutdownThis will:
- Clean all build artifacts
- Remove Terraform state
- Stop and remove the LocalStack container
MIT