resource "aws_cloudwatch_log_group" "po_email_processor" { name = "/aws/lambda/po-email-processor" retention_in_days = 60 lifecycle { prevent_destroy = true } } resource "aws_cloudwatch_log_group" "po_web_ui" { name = "/aws/lambda/po-web-ui" retention_in_days = 60 lifecycle { prevent_destroy = true } } resource "aws_cloudwatch_log_group" "po_site_extractor" { name = "/aws/lambda/po-ingest-site-extractor" retention_in_days = 60 lifecycle { prevent_destroy = true } } resource "aws_lambda_function" "po_email_processor" { function_name = "po-email-processor" role = aws_iam_role.po_email_processor.arn handler = "handler.handler" runtime = "python3.12" architectures = ["arm64"] memory_size = 256 timeout = 60 s3_bucket = aws_s3_bucket.artifacts.id s3_key = aws_s3_object.lambda["po_email_processor"].key source_code_hash = data.archive_file.lambda["po_email_processor"].output_base64sha256 dead_letter_config { target_arn = aws_sqs_queue.po_email_processor_dlq.arn } environment { variables = { PO_TABLE = aws_dynamodb_table.purchase_orders.name ALLOWED_DKIM_DOMAINS = "amazon.coupahost.com" BEDROCK_MODEL_ID = local.bedrock_model_id } } depends_on = [ aws_s3_object.lambda, aws_cloudwatch_log_group.po_email_processor, aws_iam_role_policy_attachment.po_email_processor_basic, aws_iam_role_policy.po_email_processor_s3, aws_iam_role_policy.po_email_processor_ddb, aws_iam_role_policy.po_email_processor_kms, aws_iam_role_policy.po_email_processor_bedrock, aws_iam_role_policy.po_email_processor_dlq, ] } resource "aws_lambda_function" "po_web_ui" { function_name = "po-web-ui" role = aws_iam_role.po_web_ui.arn handler = "handler.handler" runtime = "python3.12" architectures = ["arm64"] memory_size = 256 timeout = 60 s3_bucket = aws_s3_bucket.artifacts.id s3_key = aws_s3_object.lambda["po_web_ui"].key source_code_hash = data.archive_file.lambda["po_web_ui"].output_base64sha256 environment { variables = { PO_TABLE = aws_dynamodb_table.purchase_orders.name WEB_UI_AUTH_TOKEN_SECRET_ARN = var.web_ui_auth_token_secret_arn } } depends_on = [ aws_s3_object.lambda, aws_cloudwatch_log_group.po_web_ui, aws_iam_role_policy_attachment.po_web_ui_basic, aws_iam_role_policy.po_web_ui_ddb, aws_iam_role_policy.po_web_ui_kms, aws_iam_role_policy.po_web_ui_secrets, ] } resource "aws_lambda_function" "po_site_extractor" { function_name = "po-ingest-site-extractor" role = aws_iam_role.po_site_extractor.arn handler = "handler.handler" runtime = "python3.12" architectures = ["arm64"] memory_size = 256 timeout = 60 s3_bucket = aws_s3_bucket.artifacts.id s3_key = aws_s3_object.lambda["po_site_extractor"].key source_code_hash = data.archive_file.lambda["po_site_extractor"].output_base64sha256 environment { variables = { VERIFIED_SITES_TABLE = aws_dynamodb_table.verified_sites.name PENDING_REVIEW_TABLE = aws_dynamodb_table.pending_site_review.name } } depends_on = [ aws_s3_object.lambda, aws_cloudwatch_log_group.po_site_extractor, aws_iam_role_policy_attachment.po_site_extractor_basic, aws_iam_role_policy.po_site_extractor_ddb, aws_iam_role_policy.po_site_extractor_kms, ] } resource "aws_lambda_event_source_mapping" "po_site_extractor" { event_source_arn = aws_dynamodb_table.purchase_orders.stream_arn function_name = aws_lambda_function.po_site_extractor.arn starting_position = "TRIM_HORIZON" batch_size = 10 maximum_batching_window_in_seconds = 30 bisect_batch_on_function_error = true maximum_retry_attempts = 3 parallelization_factor = 1 enabled = true }