############################################ # 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}/*/*" }