locals { name_prefix = "${var.project_name}-${var.environment}" common_tags = { Application = "Quantum" Environment = var.environment ManagedBy = "OpenTofu" Runtime = "LocalStack" } } data "archive_file" "quantum_lambda" { type = "zip" source_file = "${path.module}/lambda/handler.py" output_path = "${path.module}/build/quantum_lambda.zip" } resource "aws_s3_bucket" "quantum_artifacts" { bucket = "${local.name_prefix}-artifacts" force_destroy = true tags = merge(local.common_tags, { Name = "${local.name_prefix}-artifacts" }) } resource "aws_s3_bucket_versioning" "quantum_artifacts" { bucket = aws_s3_bucket.quantum_artifacts.id versioning_configuration { status = "Enabled" } } resource "aws_s3_object" "sample_config" { bucket = aws_s3_bucket.quantum_artifacts.id key = "config/quantum-${var.environment}.json" content_type = "application/json" content = jsonencode({ appName = "Quantum" environment = var.environment featureToggle = "localstack" owner = "platform-team" }) tags = local.common_tags } resource "aws_sqs_queue" "quantum_dlq" { name = "${local.name_prefix}-events-dlq" message_retention_seconds = 1209600 tags = merge(local.common_tags, { Name = "${local.name_prefix}-events-dlq" }) } resource "aws_sqs_queue" "quantum_events" { name = "${local.name_prefix}-events" visibility_timeout_seconds = 45 message_retention_seconds = 345600 redrive_policy = jsonencode({ deadLetterTargetArn = aws_sqs_queue.quantum_dlq.arn maxReceiveCount = 3 }) tags = merge(local.common_tags, { Name = "${local.name_prefix}-events" }) } resource "aws_secretsmanager_secret" "quantum_app" { name = "${local.name_prefix}/app" recovery_window_in_days = 0 tags = merge(local.common_tags, { Name = "${local.name_prefix}-app-secret" }) } resource "aws_secretsmanager_secret_version" "quantum_app" { secret_id = aws_secretsmanager_secret.quantum_app.id secret_string = jsonencode({ databaseUrl = "postgres://quantum_user:change-me@quantum-${var.environment}-db.local:5432/quantum" apiKey = "qtm_${var.environment}_change_me" jwtSecret = "change-me-${var.environment}" }) } resource "aws_iam_role" "quantum_lambda" { name = "${local.name_prefix}-lambda-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Principal = { Service = "lambda.amazonaws.com" } Action = "sts:AssumeRole" } ] }) tags = local.common_tags } resource "aws_iam_policy" "quantum_lambda" { name = "${local.name_prefix}-lambda-policy" description = "Permissions for the Quantum Lambda function on LocalStack." policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ] Resource = "*" }, { Effect = "Allow" Action = [ "sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes" ] Resource = aws_sqs_queue.quantum_events.arn }, { Effect = "Allow" Action = [ "secretsmanager:GetSecretValue" ] Resource = aws_secretsmanager_secret.quantum_app.arn }, { Effect = "Allow" Action = [ "s3:GetObject", "s3:PutObject", "s3:ListBucket" ] Resource = [ aws_s3_bucket.quantum_artifacts.arn, "${aws_s3_bucket.quantum_artifacts.arn}/*" ] } ] }) tags = local.common_tags } resource "aws_iam_role_policy_attachment" "quantum_lambda" { role = aws_iam_role.quantum_lambda.name policy_arn = aws_iam_policy.quantum_lambda.arn } resource "aws_cloudwatch_log_group" "quantum_lambda" { name = "/aws/lambda/${local.name_prefix}-processor" retention_in_days = 14 tags = local.common_tags } resource "aws_lambda_function" "quantum_processor" { function_name = "${local.name_prefix}-processor" description = "Event processor for the Quantum application." role = aws_iam_role.quantum_lambda.arn runtime = "python3.11" handler = "handler.lambda_handler" filename = data.archive_file.quantum_lambda.output_path source_code_hash = data.archive_file.quantum_lambda.output_base64sha256 timeout = 30 memory_size = 256 environment { variables = { APP_NAME = "Quantum" BUCKET_NAME = aws_s3_bucket.quantum_artifacts.bucket SECRET_NAME = aws_secretsmanager_secret.quantum_app.name QUEUE_URL = aws_sqs_queue.quantum_events.url } } depends_on = [ aws_cloudwatch_log_group.quantum_lambda, aws_iam_role_policy_attachment.quantum_lambda ] tags = local.common_tags } resource "aws_lambda_event_source_mapping" "quantum_events" { event_source_arn = aws_sqs_queue.quantum_events.arn function_name = aws_lambda_function.quantum_processor.arn batch_size = 5 enabled = false }