openclaw/workers/ppal-aws/terraform/iam.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

132 lines
3.1 KiB
HCL

resource "aws_iam_role" "lambda_role" {
name = "${var.project_name}-lambda-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
tags = {
Name = "${var.project_name}-lambda-role"
}
}
# Basic Lambda execution permissions
resource "aws_iam_role_policy_attachment" "lambda_basic" {
role = aws_iam_role.lambda_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
# DynamoDB permissions
resource "aws_iam_role_policy" "lambda_dynamodb" {
name = "${var.project_name}-dynamodb-policy"
role = aws_iam_role.lambda_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem"
]
Resource = [
aws_dynamodb_table.users.arn,
aws_dynamodb_table.conversations.arn,
"${aws_dynamodb_table.users.arn}/index/*",
"${aws_dynamodb_table.conversations.arn}/index/*"
]
}
]
})
}
# Secrets Manager permissions
resource "aws_iam_role_policy" "lambda_secrets" {
name = "${var.project_name}-secrets-policy"
role = aws_iam_role.lambda_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
]
Resource = [
aws_secretsmanager_secret.discord_bot_token.arn,
aws_secretsmanager_secret.discord_public_key.arn,
aws_secretsmanager_secret.github_token.arn,
aws_secretsmanager_secret.openai_api_key.arn
]
}
]
})
}
# CloudWatch Logs permissions
resource "aws_iam_role_policy" "lambda_logs" {
name = "${var.project_name}-logs-policy"
role = aws_iam_role.lambda_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = "arn:aws:logs:${var.aws_region}:*:log-group:/aws/lambda/${var.project_name}*"
}
]
})
}
# ECR permissions for pulling Lambda image
resource "aws_iam_role_policy" "lambda_ecr" {
name = "${var.project_name}-ecr-policy"
role = aws_iam_role.lambda_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability"
]
Resource = "${data.aws_ecr_repository.lambda.arn}"
},
{
Effect = "Allow"
Action = [
"ecr:GetAuthorizationToken"
]
Resource = "*"
}
]
})
}