Model/infrastructure/terraform/modules/lambda_with_api_gateway/main.tf
2026-03-18 14:53:44 +00:00

117 lines
3.5 KiB
HCL

############################################
# IAM role
############################################
module "role" {
source = "../lambda_execution_role"
name = "${var.name}-lambda-${var.stage}"
}
############################################
# Cloudwatch log group
############################################
resource "aws_cloudwatch_log_group" "api_logs" {
name = "/aws/apigateway/${var.name}-${var.stage}"
retention_in_days = 14
}
############################################
# Install python packages
############################################
resource "null_resource" "pip_install" {
count = var.requirements_file != null ? 1 : 0
triggers = {
always_run = timestamp()
}
provisioner "local-exec" {
command = "pip install -r ${var.requirements_file} -t ${var.source_dir} --platform manylinux2014_x86_64 --implementation cp --python-version 3.11 --only-binary=:all: --upgrade"
}
}
############################################
# Zip the source code
############################################
data "archive_file" "this" {
depends_on = [null_resource.pip_install]
type = "zip"
source_dir = var.source_dir
output_path = "${path.module}/lambda_package.zip"
excludes = var.zip_excludes
}
############################################
# Upload zip to S3
############################################
resource "aws_s3_object" "lambda_zip" {
bucket = var.artifact_bucket
key = "env:/${var.stage}/${var.name}.zip"
source = data.archive_file.this.output_path
etag = data.archive_file.this.output_md5
}
############################################
# Lambda
############################################
module "lambda" {
source = "../lambda_service_zip"
name = "${var.name}-${var.stage}"
role_arn = module.role.role_arn
s3_bucket = var.artifact_bucket
s3_key = aws_s3_object.lambda_zip.key
source_code_hash = data.archive_file.this.output_base64sha256
handler = var.handler
runtime = var.runtime
timeout = var.timeout
memory_size = var.memory_size
environment = var.environment
}
############################################
# API Gateway
############################################
resource "aws_apigatewayv2_api" "this" {
name = "${var.name}-api-${var.stage}"
protocol_type = "HTTP"
}
resource "aws_apigatewayv2_stage" "this" {
api_id = aws_apigatewayv2_api.this.id
name = "$default"
auto_deploy = true
access_log_settings {
destination_arn = aws_cloudwatch_log_group.api_logs.arn
format = jsonencode({
requestId = "$context.requestId"
domainName = "$context.domainName"
path = "$context.path"
status = "$context.status"
sourceIp = "$context.identity.sourceIp"
userAgent = "$context.identity.userAgent"
})
}
}
resource "aws_apigatewayv2_integration" "this" {
api_id = aws_apigatewayv2_api.this.id
integration_type = "AWS_PROXY"
integration_uri = module.lambda.lambda_arn
payload_format_version = "2.0"
}
resource "aws_apigatewayv2_route" "catch_all" {
api_id = aws_apigatewayv2_api.this.id
route_key = "$default"
target = "integrations/${aws_apigatewayv2_integration.this.id}"
}
resource "aws_lambda_permission" "apigw_invoke" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = module.lambda.lambda_arn
principal = "apigateway.amazonaws.com"
source_arn = "${aws_apigatewayv2_api.this.execution_arn}/*/*"
}