Learn how to efficiently create and manage API proxies on AWS API Gateway using Terraform for streamlined infrastructure provisioning and automated workflows.
This guide provides a step-by-step approach to building a basic API Gateway proxy using Terraform. We'll establish a simple API endpoint that leverages a Lambda function for backend logic. The process involves defining the API Gateway resource, creating a resource within it, defining a method for the resource, configuring the integration type, deploying the API Gateway changes, and finally, configuring a stage for the deployment.
resource "aws_api_gateway_rest_api" "example" {
name = "example"
}
resource "aws_api_gateway_resource" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
parent_id = aws_api_gateway_rest_api.example.root_resource_id
path_part = "example"
}
resource "aws_api_gateway_method" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
resource_id = aws_api_gateway_resource.example.id
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
resource_id = aws_api_gateway_resource.example.id
http_method = aws_api_gateway_method.example.http_method
integration_type = "AWS_PROXY"
integration_target_arn = aws_lambda_function.example.invoke_arn
}
resource "aws_api_gateway_deployment" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
triggers = {
redeployment = sha1(jsonencode(aws_api_gateway_integration.example))
}
}
resource "aws_api_gateway_stage" "example" {
deployment_id = aws_api_gateway_deployment.example.id
rest_api_id = aws_api_gateway_rest_api.example.id
stage_name = "example"
}
This sets up a basic API Gateway proxy with a single GET method integrated with a Lambda function. You can customize it further by adding resources, methods, integrations, authorizers, and other features as needed.
This Terraform code defines infrastructure on AWS. It sets up a simple Node.js Lambda function that returns "Hello from Lambda!" when invoked. An API Gateway is configured with a GET method on the "/example" resource, integrated with the Lambda function. This allows invoking the function through HTTP requests to the provided API Gateway endpoint URL. The code also sets up the necessary IAM roles and policies for the Lambda function to operate.
# Configure the AWS Provider
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
# Configure variables (replace with your values)
variable "region" {
default = "us-east-1"
}
variable "lambda_function_name" {
default = "example_function"
}
# Create a Lambda function (replace with your function code)
resource "aws_lambda_function" "example" {
function_name = var.lambda_function_name
runtime = "nodejs16.x"
handler = "index.handler"
role = aws_iam_role.lambda_exec.arn
# Replace with your actual function code
code = <<EOF
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
EOF
}
# Create an IAM role for the Lambda function
resource "aws_iam_role" "lambda_exec" {
name = "lambda_exec_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
# Attach the AWSLambdaBasicExecutionRole policy to the Lambda role
resource "aws_iam_role_policy_attachment" "lambda_policy" {
role = aws_iam_role.lambda_exec.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
# Create an API Gateway REST API
resource "aws_api_gateway_rest_api" "example" {
name = "example_api"
}
# Create a resource within the API Gateway
resource "aws_api_gateway_resource" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
parent_id = aws_api_gateway_rest_api.example.root_resource_id
path_part = "example"
}
# Define a GET method for the resource
resource "aws_api_gateway_method" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
resource_id = aws_api_gateway_resource.example.id
http_method = "GET"
authorization = "NONE"
}
# Configure Lambda integration for the method
resource "aws_api_gateway_integration" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
resource_id = aws_api_gateway_resource.example.id
http_method = aws_api_gateway_method.example.http_method
integration_type = "AWS_PROXY"
integration_target_arn = aws_lambda_function.example.invoke_arn
}
# Deploy the API Gateway changes
resource "aws_api_gateway_deployment" "example" {
rest_api_id = aws_api_gateway_rest_api.example.id
triggers = {
redeployment = sha1(jsonencode(aws_api_gateway_integration.example))
}
}
# Configure a stage for the deployment
resource "aws_api_gateway_stage" "example" {
deployment_id = aws_api_gateway_deployment.example.id
rest_api_id = aws_api_gateway_rest_api.example.id
stage_name = "example"
}
# Output the API Gateway endpoint URL
output "api_gateway_url" {
value = "https://${aws_api_gateway_rest_api.example.id}.execute-api.${var.region}.amazonaws.com/${aws_api_gateway_stage.example.stage_name}/example"
}
Explanation:
Provider and Variables:
Lambda Function:
API Gateway Resources:
/example
within the API./example
resource.API Gateway Integration:
Deployment and Stage:
Output:
To use this code:
variable "lambda_function_name"
with your desired Lambda function name.terraform init
terraform apply
api_gateway_url
. You can use this URL to make GET requests to your API.1. API Gateway Resource:
name
attribute defines the friendly name for your API in the AWS console.description
attribute to document the purpose of your API.2. API Gateway Resource:
/example
.path_part
values to define your API's structure.3. API Gateway Method:
GET
in this case) that can be used to access the resource.POST
, PUT
, DELETE
) for a single resource.authorization
attribute controls access to the method. NONE
means no authorization is required. Consider using other options like AWS_IAM
or custom authorizers for production APIs.4. API Gateway Integration:
AWS_PROXY
means API Gateway forwards the entire request to the Lambda function and returns the function's response directly.integration_target_arn
points to the Lambda function that will handle the requests.5. API Gateway Deployment:
triggers
attribute ensures a new deployment occurs whenever the integration configuration changes.6. API Gateway Stage:
dev
, test
, prod
).stage_name
attribute defines the URL path for accessing this stage.General Notes:
This code defines a simple REST API using AWS API Gateway and Terraform. Here's a breakdown:
In essence, this code sets up a basic API endpoint that, when called with a GET request, invokes a specified Lambda function.
This guide demonstrated how to create a basic API Gateway proxy integrated with a Lambda function using Terraform. By following these steps, you can establish a foundational understanding of leveraging Terraform to manage and automate your API Gateway infrastructure. Remember to explore additional API Gateway features and security best practices as you develop more complex and robust APIs.