meal-order-manager/terraform/lambda.tf
Adam Moussa 62f61f61d1
Some checks failed
Build Lambda Layer / build (push) Has been cancelled
feat(meals): send weekly deductions to paychex checkcomponents (PLAT-154) (#184)
* feat(meals): send weekly deductions to paychex checkcomponents (PLAT-154)

* fix(meals): round checkcomponents amounts half-up

Keep SQS deduction amounts on the same rounding path as submit_order so extra-precision totals cannot diverge by a cent.
2026-09-03 22:04:02 +00:00

240 lines
7.9 KiB
HCL

# The shared layer and the seven functions.
#
# Packages come from the artifacts bucket (see artifacts.tf). Function packages
# contain the handler only: boto3 comes from the runtime, and fpdf2 plus the
# `shared` package come from the layer.
resource "aws_lambda_layer_version" "shared" {
layer_name = "${local.project}-shared"
description = "fpdf2 and the shared package for meal-order-manager"
s3_bucket = aws_s3_bucket.artifacts.id
s3_key = aws_s3_object.shared_layer.key
source_code_hash = data.archive_file.shared_layer.output_base64sha256
compatible_runtimes = ["python3.12"]
compatible_architectures = ["arm64"]
}
# ---------------------------------------------------------------------------
# submit-order — HTTP API handler for the order form and the admin surface
# ---------------------------------------------------------------------------
resource "aws_lambda_function" "submit_order" {
function_name = "${local.project}-submit-order"
role = aws_iam_role.submit_order.arn
handler = "handler.lambda_handler"
runtime = "python3.12"
architectures = ["arm64"]
memory_size = 128
timeout = 10
s3_bucket = aws_s3_bucket.artifacts.id
s3_key = aws_s3_object.function["submit_order"].key
source_code_hash = data.archive_file.function["submit_order"].output_base64sha256
layers = [aws_lambda_layer_version.shared.arn]
environment {
variables = merge(local.common_env, {
SLACK_NOTIFIER_ARN = aws_lambda_function.slack_notifier.arn
GOOGLE_CLIENT_ID_PARAM = local.google_client_id_param
})
}
depends_on = [
aws_cloudwatch_log_group.function,
aws_iam_role_policy.submit_order,
aws_iam_role_policy_attachment.submit_order_basic,
]
}
# ---------------------------------------------------------------------------
# admin-authorizer — validates the Google ID token for every /api/admin route
# ---------------------------------------------------------------------------
resource "aws_lambda_function" "admin_authorizer" {
function_name = "${local.project}-admin-authorizer"
role = aws_iam_role.admin_authorizer.arn
handler = "handler.lambda_handler"
runtime = "python3.12"
architectures = ["arm64"]
memory_size = 128
timeout = 10
s3_bucket = aws_s3_bucket.artifacts.id
s3_key = aws_s3_object.function["admin_authorizer"].key
source_code_hash = data.archive_file.function["admin_authorizer"].output_base64sha256
layers = [aws_lambda_layer_version.shared.arn]
environment {
variables = merge(local.common_env, {
GOOGLE_CLIENT_ID_PARAM = local.google_client_id_param
})
}
depends_on = [
aws_cloudwatch_log_group.function,
aws_iam_role_policy.admin_authorizer,
aws_iam_role_policy_attachment.admin_authorizer_basic,
]
}
# ---------------------------------------------------------------------------
# close-form — closes the weekly order window, then fans out to aggregation
# ---------------------------------------------------------------------------
resource "aws_lambda_function" "close_form" {
function_name = "${local.project}-close-form"
role = aws_iam_role.close_form.arn
handler = "handler.lambda_handler"
runtime = "python3.12"
architectures = ["arm64"]
memory_size = 128
timeout = 30
s3_bucket = aws_s3_bucket.artifacts.id
s3_key = aws_s3_object.function["close_form"].key
source_code_hash = data.archive_file.function["close_form"].output_base64sha256
layers = [aws_lambda_layer_version.shared.arn]
environment {
variables = merge(local.common_env, {
AGGREGATE_FUNCTION_ARN = aws_lambda_function.aggregate_orders.arn
})
}
depends_on = [
aws_cloudwatch_log_group.function,
aws_iam_role_policy.close_form,
aws_iam_role_policy_attachment.close_form_basic,
]
}
# ---------------------------------------------------------------------------
# aggregate-orders — rolls the week's orders into CSV and PDF artifacts
# ---------------------------------------------------------------------------
resource "aws_lambda_function" "aggregate_orders" {
function_name = "${local.project}-aggregate-orders"
role = aws_iam_role.aggregate_orders.arn
handler = "handler.lambda_handler"
runtime = "python3.12"
architectures = ["arm64"]
memory_size = 256
timeout = 60
s3_bucket = aws_s3_bucket.artifacts.id
s3_key = aws_s3_object.function["aggregate_orders"].key
source_code_hash = data.archive_file.function["aggregate_orders"].output_base64sha256
layers = [aws_lambda_layer_version.shared.arn]
environment {
variables = merge(local.common_env, {
SLACK_NOTIFIER_ARN = aws_lambda_function.slack_notifier.arn
CHECKCOMPONENTS_QUEUE_URL = var.checkcomponents_queue_url
})
}
depends_on = [
aws_cloudwatch_log_group.function,
aws_iam_role_policy.aggregate_orders,
aws_iam_role_policy_attachment.aggregate_orders_basic,
]
}
# ---------------------------------------------------------------------------
# slack-notifier — reminders and summaries into Slack
# ---------------------------------------------------------------------------
resource "aws_lambda_function" "slack_notifier" {
function_name = "${local.project}-slack-notifier"
role = aws_iam_role.slack_notifier.arn
handler = "handler.lambda_handler"
runtime = "python3.12"
architectures = ["arm64"]
memory_size = 128
timeout = 30
s3_bucket = aws_s3_bucket.artifacts.id
s3_key = aws_s3_object.function["slack_notifier"].key
source_code_hash = data.archive_file.function["slack_notifier"].output_base64sha256
layers = [aws_lambda_layer_version.shared.arn]
environment {
variables = local.common_env
}
depends_on = [
aws_cloudwatch_log_group.function,
aws_iam_role_policy.slack_notifier,
aws_iam_role_policy_attachment.slack_notifier_basic,
]
}
# ---------------------------------------------------------------------------
# sync-roster — pulls the employee roster from Slack ahead of the menu publish
# ---------------------------------------------------------------------------
resource "aws_lambda_function" "sync_roster" {
function_name = "${local.project}-sync-roster"
role = aws_iam_role.sync_roster.arn
handler = "handler.lambda_handler"
runtime = "python3.12"
architectures = ["arm64"]
memory_size = 128
timeout = 60
s3_bucket = aws_s3_bucket.artifacts.id
s3_key = aws_s3_object.function["sync_roster"].key
source_code_hash = data.archive_file.function["sync_roster"].output_base64sha256
layers = [aws_lambda_layer_version.shared.arn]
environment {
variables = local.common_env
}
depends_on = [
aws_cloudwatch_log_group.function,
aws_iam_role_policy.sync_roster,
aws_iam_role_policy_attachment.sync_roster_basic,
]
}
# ---------------------------------------------------------------------------
# email-report — emails the weekly payroll deduction report
# ---------------------------------------------------------------------------
resource "aws_lambda_function" "email_report" {
function_name = "${local.project}-email-report"
role = aws_iam_role.email_report.arn
handler = "handler.lambda_handler"
runtime = "python3.12"
architectures = ["arm64"]
memory_size = 128
timeout = 30
s3_bucket = aws_s3_bucket.artifacts.id
s3_key = aws_s3_object.function["email_report"].key
source_code_hash = data.archive_file.function["email_report"].output_base64sha256
layers = [aws_lambda_layer_version.shared.arn]
environment {
variables = merge(local.common_env, {
PAYROLL_EMAIL = var.payroll_email
SENDER_EMAIL = var.sender_email
})
}
depends_on = [
aws_cloudwatch_log_group.function,
aws_iam_role_policy.email_report,
aws_iam_role_policy_attachment.email_report_basic,
]
}