############################################ # Credentials from Secrets Manager (resolved at plan/apply time and baked into # env vars). The SES SMTP credentials are an IAM *user* (see modules/ses), so # the Lambda authenticates to SES over SMTP with them — the execution role needs # neither ses:* nor runtime secretsmanager access. ############################################ data "aws_secretsmanager_secret_version" "db_credentials" { secret_id = "${var.stage}/assessment_model/db_credentials" } data "aws_secretsmanager_secret_version" "ses_smtp" { secret_id = "${var.stage}/ses/smtp_credentials" } locals { db_credentials = jsondecode(data.aws_secretsmanager_secret_version.db_credentials.secret_string) ses_smtp = jsondecode(data.aws_secretsmanager_secret_version.ses_smtp.secret_string) document_exports_bucket = "retrofit-document-exports-${var.stage}" # Source buckets the uploaded_files rows point at (read for packaging). # OPEN QUESTION: confirm this is the closed set — if files can live in # arbitrary buckets, widen to ["arn:aws:s3:::*"]. source_bucket_arns = [ "arn:aws:s3:::retrofit-data-${var.stage}", "arn:aws:s3:::retrofit-energy-assessments-${var.stage}", ] } ############################################ # Lambda + SQS queue + trigger ############################################ module "lambda" { source = "../../modules/lambda_with_sqs" name = var.lambda_name stage = var.stage image_uri = local.image_uri reserved_concurrent_executions = var.reserved_concurrent_executions batch_size = var.batch_size maximum_concurrency = var.maximum_concurrency timeout = 900 memory_size = 3008 # A Download Package can be several GB; it is streamed to /tmp before the # multipart upload (ADR-0060), so raise ephemeral storage to the 10 GB max. ephemeral_storage_size = 10240 environment = { STAGE = var.stage LOG_LEVEL = "info" POSTGRES_USERNAME = local.db_credentials.db_assessment_model_username POSTGRES_PASSWORD = local.db_credentials.db_assessment_model_password POSTGRES_HOST = var.db_host POSTGRES_DATABASE = var.db_name POSTGRES_PORT = var.db_port DOCUMENT_EXPORTS_BUCKET = local.document_exports_bucket # SES SMTP — IAM-user credentials sourced from Secrets Manager (modules/ses). SES_SMTP_HOST = "email-smtp.eu-west-2.amazonaws.com" SES_SMTP_PORT = "587" SES_SMTP_USERNAME = local.ses_smtp.username SES_SMTP_PASSWORD = local.ses_smtp.password SES_SMTP_FROM_ADDRESS = var.ses_from_address } } ############################################ # IAM: read uploaded documents from their source buckets ############################################ module "s3_read" { source = "../../modules/s3_iam_policy" policy_name = "BulkDocumentDownloadS3Read-${var.stage}" policy_description = "Allow bulk_document_download Lambda to read uploaded_files objects from their source buckets" bucket_arns = local.source_bucket_arns actions = ["s3:GetObject", "s3:ListBucket"] resource_paths = ["/*"] } resource "aws_iam_role_policy_attachment" "s3_read" { role = module.lambda.role_name policy_arn = module.s3_read.policy_arn } ############################################ # IAM: write + read the assembled ZIP on the dedicated exports bucket. # GetObject is required so the Lambda-signed presigned GET URL resolves. ############################################ module "s3_exports" { source = "../../modules/s3_iam_policy" policy_name = "BulkDocumentDownloadS3Exports-${var.stage}" policy_description = "Allow bulk_document_download Lambda to write and presign-read Download Packages on the exports bucket" bucket_arns = ["arn:aws:s3:::${local.document_exports_bucket}"] actions = ["s3:PutObject", "s3:GetObject"] resource_paths = ["/*"] } resource "aws_iam_role_policy_attachment" "s3_exports" { role = module.lambda.role_name policy_arn = module.s3_exports.policy_arn } # NOTE: no ses:* on the role — the handler sends over SMTP with the SES IAM-user # credentials injected above.