# Provider configuration
provider "aws" {
region = var.aws_region
}
# Data source for current AWS account
data "aws_caller_identity" "current" {}
# Data source for current AWS region
data "aws_region" "current" {}
# Archive Lambda function code
data "archive_file" "mcp_gateway_zip" {
type = "zip"
source_dir = "${path.module}/../gateway"
output_path = "${path.module}/lambda_packages/mcp_gateway.zip"
excludes = ["__pycache__", "*.pyc", ".pytest_cache"]
}
# Weather Tool - package only the specific file
data "archive_file" "weather_tool_zip" {
type = "zip"
source_file = "${path.module}/../tools/lambda_functions/weather_tool.py"
output_path = "${path.module}/lambda_packages/weather_tool.zip"
}
# Calculator Tool - package only the specific file
data "archive_file" "calculator_tool_zip" {
type = "zip"
source_file = "${path.module}/../tools/lambda_functions/calculator_tool.py"
output_path = "${path.module}/lambda_packages/calculator_tool.zip"
}
# Data Lookup Tool - package only the specific file
data "archive_file" "data_lookup_tool_zip" {
type = "zip"
source_file = "${path.module}/../tools/lambda_functions/data_lookup_tool.py"
output_path = "${path.module}/lambda_packages/data_lookup_tool.zip"
}
# REST API Server - package the Lambda version
data "archive_file" "rest_api_server_zip" {
type = "zip"
source_file = "${path.module}/../tools/rest_apis/rest_api_lambda.py"
output_path = "${path.module}/lambda_packages/rest_api_server.zip"
}
# IAM Role for MCP Gateway Lambda
resource "aws_iam_role" "mcp_gateway_role" {
name = "${var.environment}-mcp-gateway-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
# IAM Policy for MCP Gateway to invoke other Lambda functions
resource "aws_iam_role_policy" "mcp_gateway_policy" {
name = "${var.environment}-mcp-gateway-policy"
role = aws_iam_role.mcp_gateway_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "arn:aws:logs:*:*:*"
},
{
Effect = "Allow"
Action = [
"lambda:InvokeFunction"
]
Resource = [
aws_lambda_function.weather_tool.arn,
aws_lambda_function.calculator_tool.arn,
aws_lambda_function.data_lookup_tool.arn
]
},
{
Effect = "Allow"
Action = [
"sts:GetCallerIdentity"
]
Resource = "*"
}
]
})
}
# IAM Role for Tool Lambda Functions
resource "aws_iam_role" "tool_lambda_role" {
name = "${var.environment}-tool-lambda-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
# IAM Policy for Tool Lambda Functions
resource "aws_iam_role_policy" "tool_lambda_policy" {
name = "${var.environment}-tool-lambda-policy"
role = aws_iam_role.tool_lambda_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "arn:aws:logs:*:*:*"
}
]
})
}
# MCP Gateway Lambda Function
resource "aws_lambda_function" "mcp_gateway" {
filename = data.archive_file.mcp_gateway_zip.output_path
function_name = "${var.environment}-mcp-gateway"
role = aws_iam_role.mcp_gateway_role.arn
handler = "lambda_handler.lambda_handler"
source_code_hash = data.archive_file.mcp_gateway_zip.output_base64sha256
runtime = "python3.11"
timeout = 30
memory_size = 512
layers = compact([
var.python_dependencies_layer_arn != "" ? var.python_dependencies_layer_arn : null,
var.httpx_layer_arn != "" ? var.httpx_layer_arn : null
])
environment {
variables = {
ENVIRONMENT = var.environment
REST_API_SERVER_API_ID = aws_api_gateway_rest_api.rest_api_server_api.id
}
}
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
# Weather Tool Lambda Function
resource "aws_lambda_function" "weather_tool" {
filename = data.archive_file.weather_tool_zip.output_path
function_name = "${var.environment}-weather-tool"
role = aws_iam_role.tool_lambda_role.arn
handler = "weather_tool.lambda_handler"
source_code_hash = data.archive_file.weather_tool_zip.output_base64sha256
runtime = "python3.11"
timeout = 30
memory_size = 256
environment {
variables = {
ENVIRONMENT = var.environment
}
}
tags = merge(
{
Environment = var.environment
Project = "mcp-gateway"
},
var.tags
)
}
# Calculator Tool Lambda Function
resource "aws_lambda_function" "calculator_tool" {
filename = data.archive_file.calculator_tool_zip.output_path
function_name = "${var.environment}-calculator-tool"
role = aws_iam_role.tool_lambda_role.arn
handler = "calculator_tool.lambda_handler"
source_code_hash = data.archive_file.calculator_tool_zip.output_base64sha256
runtime = "python3.11"
timeout = 30
memory_size = 256
environment {
variables = {
ENVIRONMENT = var.environment
}
}
tags = merge(
{
Environment = var.environment
Project = "mcp-gateway"
},
var.tags
)
}
# Data Lookup Tool Lambda Function
resource "aws_lambda_function" "data_lookup_tool" {
filename = data.archive_file.data_lookup_tool_zip.output_path
function_name = "${var.environment}-data-lookup-tool"
role = aws_iam_role.tool_lambda_role.arn
handler = "data_lookup_tool.lambda_handler"
source_code_hash = data.archive_file.data_lookup_tool_zip.output_base64sha256
runtime = "python3.11"
timeout = 30
memory_size = 256
environment {
variables = {
ENVIRONMENT = var.environment
}
}
tags = merge(
{
Environment = var.environment
Project = "mcp-gateway"
},
var.tags
)
}
# REST API Server Lambda Function
resource "aws_lambda_function" "rest_api_server" {
filename = data.archive_file.rest_api_server_zip.output_path
function_name = "${var.environment}-rest-api-server"
role = aws_iam_role.tool_lambda_role.arn
handler = "rest_api_lambda.lambda_handler"
source_code_hash = data.archive_file.rest_api_server_zip.output_base64sha256
runtime = "python3.11"
timeout = 30
memory_size = 512
layers = compact([
var.python_dependencies_layer_arn != "" ? var.python_dependencies_layer_arn : null,
var.httpx_layer_arn != "" ? var.httpx_layer_arn : null
])
environment {
variables = {
ENVIRONMENT = var.environment
# Force update when layer changes
LAYER_VERSION = var.python_dependencies_layer_arn != "" ? split(":", var.python_dependencies_layer_arn)[7] : "none"
}
}
tags = merge(
{
Environment = var.environment
Project = "mcp-gateway"
},
var.tags
)
}
# REST API Server API Gateway
resource "aws_api_gateway_rest_api" "rest_api_server_api" {
name = "${var.environment}-rest-api-server"
description = "REST API Server for MCP Tools"
endpoint_configuration {
types = ["REGIONAL"]
}
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
# REST API Server - Proxy Resource (catch-all)
resource "aws_api_gateway_resource" "rest_api_proxy" {
rest_api_id = aws_api_gateway_rest_api.rest_api_server_api.id
parent_id = aws_api_gateway_rest_api.rest_api_server_api.root_resource_id
path_part = "{proxy+}"
}
# REST API Server - Proxy Method
resource "aws_api_gateway_method" "rest_api_proxy_method" {
rest_api_id = aws_api_gateway_rest_api.rest_api_server_api.id
resource_id = aws_api_gateway_resource.rest_api_proxy.id
http_method = "ANY"
authorization = "NONE"
}
# REST API Server - Proxy Integration
resource "aws_api_gateway_integration" "rest_api_proxy_integration" {
rest_api_id = aws_api_gateway_rest_api.rest_api_server_api.id
resource_id = aws_api_gateway_resource.rest_api_proxy.id
http_method = aws_api_gateway_method.rest_api_proxy_method.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.rest_api_server.invoke_arn
}
# REST API Server - Root Method
resource "aws_api_gateway_method" "rest_api_root_method" {
rest_api_id = aws_api_gateway_rest_api.rest_api_server_api.id
resource_id = aws_api_gateway_rest_api.rest_api_server_api.root_resource_id
http_method = "ANY"
authorization = "NONE"
}
# REST API Server - Root Integration
resource "aws_api_gateway_integration" "rest_api_root_integration" {
rest_api_id = aws_api_gateway_rest_api.rest_api_server_api.id
resource_id = aws_api_gateway_rest_api.rest_api_server_api.root_resource_id
http_method = aws_api_gateway_method.rest_api_root_method.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.rest_api_server.invoke_arn
}
# Lambda Permission for REST API Server API Gateway
resource "aws_lambda_permission" "rest_api_server_api_gateway_invoke" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.rest_api_server.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_api_gateway_rest_api.rest_api_server_api.execution_arn}/*/*"
}
# REST API Server API Gateway Deployment
resource "aws_api_gateway_deployment" "rest_api_server_deployment" {
depends_on = [
aws_api_gateway_method.rest_api_proxy_method,
aws_api_gateway_integration.rest_api_proxy_integration,
aws_api_gateway_method.rest_api_root_method,
aws_api_gateway_integration.rest_api_root_integration,
]
rest_api_id = aws_api_gateway_rest_api.rest_api_server_api.id
stage_name = var.environment
lifecycle {
create_before_destroy = true
}
}
# API Gateway REST API (MCP Gateway)
resource "aws_api_gateway_rest_api" "mcp_gateway_api" {
name = "${var.environment}-mcp-gateway-api"
description = "MCP Gateway API for Bedrock AgentCore"
endpoint_configuration {
types = ["REGIONAL"]
}
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
# API Gateway Resource
resource "aws_api_gateway_resource" "mcp_resource" {
rest_api_id = aws_api_gateway_rest_api.mcp_gateway_api.id
parent_id = aws_api_gateway_rest_api.mcp_gateway_api.root_resource_id
path_part = "mcp"
}
# API Gateway Method
resource "aws_api_gateway_method" "mcp_method" {
rest_api_id = aws_api_gateway_rest_api.mcp_gateway_api.id
resource_id = aws_api_gateway_resource.mcp_resource.id
http_method = "POST"
authorization = "NONE"
}
# API Gateway Integration
resource "aws_api_gateway_integration" "mcp_integration" {
rest_api_id = aws_api_gateway_rest_api.mcp_gateway_api.id
resource_id = aws_api_gateway_resource.mcp_resource.id
http_method = aws_api_gateway_method.mcp_method.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.mcp_gateway.invoke_arn
}
# API Gateway Method Response
resource "aws_api_gateway_method_response" "mcp_method_response" {
rest_api_id = aws_api_gateway_rest_api.mcp_gateway_api.id
resource_id = aws_api_gateway_resource.mcp_resource.id
http_method = aws_api_gateway_method.mcp_method.http_method
status_code = "200"
response_parameters = {
"method.response.header.Mcp-Session-Id" = true
"method.response.header.Access-Control-Allow-Origin" = true
}
}
# Lambda Permission for API Gateway
resource "aws_lambda_permission" "api_gateway_invoke" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.mcp_gateway.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_api_gateway_rest_api.mcp_gateway_api.execution_arn}/*/*"
}
# API Gateway Deployment
resource "aws_api_gateway_deployment" "mcp_deployment" {
depends_on = [
aws_api_gateway_method.mcp_method,
aws_api_gateway_integration.mcp_integration,
]
rest_api_id = aws_api_gateway_rest_api.mcp_gateway_api.id
stage_name = var.environment
lifecycle {
create_before_destroy = true
}
}
# CloudWatch Log Groups
resource "aws_cloudwatch_log_group" "mcp_gateway_logs" {
name = "/aws/lambda/${aws_lambda_function.mcp_gateway.function_name}"
retention_in_days = var.log_retention_days
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
resource "aws_cloudwatch_log_group" "weather_tool_logs" {
name = "/aws/lambda/${aws_lambda_function.weather_tool.function_name}"
retention_in_days = var.log_retention_days
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
resource "aws_cloudwatch_log_group" "calculator_tool_logs" {
name = "/aws/lambda/${aws_lambda_function.calculator_tool.function_name}"
retention_in_days = var.log_retention_days
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
resource "aws_cloudwatch_log_group" "data_lookup_tool_logs" {
name = "/aws/lambda/${aws_lambda_function.data_lookup_tool.function_name}"
retention_in_days = var.log_retention_days
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}
resource "aws_cloudwatch_log_group" "rest_api_server_logs" {
name = "/aws/lambda/${aws_lambda_function.rest_api_server.function_name}"
retention_in_days = var.log_retention_days
tags = {
Environment = var.environment
Project = "mcp-gateway"
}
}