openclaw/workers/ppal-aws/terraform/lambda.tf
Shunsuke Hayashi abed5cb5cb feat(ppal-aws): add Terraform configuration for Discord Bot
Add AWS infrastructure as code for PPAL Discord Bot:
- API Gateway (HTTP API) for Discord Interactions endpoint
- Lambda function (Node.js 20.x container image)
- DynamoDB tables (users, conversations) with PAY_PER_REQUEST
- Secrets Manager for tokens (Discord, GitHub, OpenAI)
- IAM role with inline policies for Lambda execution

Files:
- versions.tf: Terraform 1.0+ with AWS provider 5.x
- variables.tf: environment, project_name, lambda config
- api_gateway.tf: HTTP API with CloudWatch logging
- lambda.tf: ECR-based Lambda with function URL
- dynamodb.tf: GSI-enabled tables with PITR & encryption
- secrets.tf: 4 secrets with placeholder values
- iam.tf: Inline policies for DynamoDB, Secrets, Logs, ECR
- outputs.tf: Endpoint URLs, ARNs (sensitive)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-25 19:04:55 +09:00

71 lines
2.2 KiB
HCL

data "aws_ecr_repository" "lambda" {
name = "${var.project_name}-lambda"
}
data "aws_ecr_image" "lambda" {
repository_name = data.aws_ecr_repository.lambda.name
image_tag = var.environment
}
resource "aws_lambda_function" "discord_handler" {
function_name = "${var.project_name}-discord-handler"
description = "PPAL Discord Bot command handler"
role = aws_iam_role.lambda_role.arn
package_type = "Image"
image_uri = "${data.aws_ecr_repository.lambda.repository_url}@${data.aws_ecr_image.lambda.image_digest}"
timeout = var.lambda_timeout
memory_size = var.lambda_memory_size
environment {
variables = {
ENVIRONMENT = var.environment
DISCORD_BOT_TOKEN_SECRET_ARN = aws_secretsmanager_secret.discord_bot_token.arn
DISCORD_PUBLIC_KEY_SECRET_ARN = aws_secretsmanager_secret.discord_public_key.arn
GITHUB_TOKEN_SECRET_ARN = aws_secretsmanager_secret.github_token.arn
OPENAI_API_KEY_SECRET_ARN = aws_secretsmanager_secret.openai_api_key.arn
USERS_TABLE_NAME = aws_dynamodb_table.users.name
CONVERSATIONS_TABLE_NAME = aws_dynamodb_table.conversations.name
}
}
logging_config {
log_format = "Text"
log_group = aws_cloudwatch_log_group.lambda_logs.name
}
depends_on = [
aws_cloudwatch_log_group.lambda_logs,
aws_iam_role_policy_attachment.lambda_basic,
aws_iam_role_policy.lambda_dynamodb,
aws_iam_role_policy.lambda_secrets,
]
tags = {
Name = "${var.project_name}-discord-handler"
}
}
resource "aws_cloudwatch_log_group" "lambda_logs" {
name = "/aws/lambda/${var.project_name}-discord-handler"
retention_in_days = 7
tags = {
Name = "${var.project_name}-lambda-logs"
}
}
resource "aws_lambda_function_url" "discord_handler" {
function_name = aws_lambda_function.discord_handler.function_name
authorization_type = "NONE"
invoke_mode = "RESPONSE_STREAM"
cors {
allow_credentials = true
allow_origins = ["https://discord.com"]
allow_methods = ["POST"]
allow_headers = ["Content-Type", "X-Discord-Timestamp", "X-Signature-Ed25519", "X-Signature-Timestamp"]
}
}