feat(aws): migrate Discord token to Secrets Manager and fix infrastructure

- Add Secrets Manager integration for Discord bot token
- Add aws_account_id and discord_token_secret_name variables
- Update ECS task definition to use Secrets Manager
- Add IAM policy for Secrets Manager access
- Fix Dockerfile .buildstamp generation for Linux compatibility
- Change VPC CIDR to 100.64.0.0/16 to avoid conflicts
- Add deployment documentation and .env.example

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Shunsuke Hayashi 2026-01-26 13:08:57 +09:00
parent 4d4a478758
commit 8ffe18aaee
8 changed files with 212 additions and 6 deletions

View File

@ -25,8 +25,8 @@ RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
# Create .buildstamp to prevent runtime rebuild
RUN mkdir -p dist && echo "$(date +%s%N)" > dist/.buildstamp
# Create .buildstamp to prevent runtime rebuild (portable timestamp)
RUN mkdir -p dist && echo "$(date +%s)000000000" > dist/.buildstamp
# Force pnpm for UI build (Bun may fail on ARM/Synology architectures)
ENV CLAWDBOT_PREFER_PNPM=1
RUN pnpm ui:install

View File

@ -0,0 +1,33 @@
# AWS Terraform Variables for Clawdbot ECS Fargate Deployment
# Copy this file to terraform.tfvars and fill in the values
# AWS Configuration
aws_region = "ap-northeast-1"
aws_account_id = "123456789012" # Your AWS account ID
# Environment
environment = "production"
project_name = "clawdbot"
# ECS Configuration
ecs_task_cpu = 256 # 0.25 vCPU
ecs_task_memory = 2048 # 2 GB
ecs_service_desired_count = 1
# Discord Token (DEPRECATED - Use Secrets Manager instead)
# discord_token = "your_bot_token_here" # DO NOT use in production
# Secrets Manager Secret Name for Discord Bot Token
discord_token_secret_name = "clawdbot/discord-token"
# Create the secret in AWS Secrets Manager before running Terraform:
# aws secretsmanager create-secret \
# --name clawdbot/discord-token \
# --secret-string "your_bot_token_here"
# DynamoDB Tables
sessions_table_name = "clawdbot-sessions"
artifacts_table_name = "clawdbot-artifacts"
# S3 Bucket
artifacts_bucket_name = "clawdbot-artifacts"
artifacts_bucket_ttl_days = 7

View File

@ -0,0 +1,135 @@
# Clawdbot AWS Deployment
ECS Fargateを使用したClawdbotのAWSデプロイメント設定
## 前提条件
- AWS CLI設定済み
- Terraformインストール済み
- Dockerインストール済み
## セットアップ手順
### 1. Discord Bot TokenをSecrets Managerに保存
```bash
# Secrets Managerにシークレットを作成
aws secretsmanager create-secret \
--name clawdbot/discord-token \
--description "Discord Bot Token for Clawdbot" \
--secret-string "your_discord_bot_token_here"
# シークレットを確認
aws secretsmanager get-secret-value --secret-id clawdbot/discord-token
```
### 2. Terraform変数の設定
`.env.example`をコピーして`terraform.tfvars`を作成:
```bash
cp .env.example terraform.tfvars
```
`terraform.tfvars`を編集して以下の値を設定:
- `aws_account_id`: AWSアカウントID
- `discord_token_secret_name`: Secrets Managerのシークレット名デフォルト: `clawdbot/discord-token`
### 3. Terraformの実行
```bash
# Terraform初期化
terraform init
# 設定確認
terraform plan
# デプロイ実行
terraform apply
```
### 4. Dockerイメージのプッシュ
```bash
# ECRログイン
aws ecr get-login-password --region ap-northeast-1 | \
docker login --username AWS --password-stdin <account-id>.dkr.ecr.ap-northeast-1.amazonaws.com
# イメージビルド
docker build -t clawdbot .
# タグ付け
docker tag clawdbot:latest <account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/clawdbot:latest
# プッシュ
docker push <account-id>.dkr.ecr.ap-northeast-1.amazonaws.com/clawdbot:latest
```
### 5. ECSサービスの更新
```bash
# 新しいタスク定義でECSサービスを更新
aws ecs update-service \
--cluster clawdbot-cluster \
--service clawdbot-service \
--force-new-deployment
```
## セキュリティベストプラクティス
- ✅ Discord Bot TokenはAWS Secrets Managerに保存
- ✅ IAMロールで最小権限の原則を適用
- ✅ S3バケットでAES256暗号化を有効化
- ✅ DynamoDBでPITRPoint-in-Time Recoveryを有効化
- ✅ VPC内にプライベートサブネットを配置
## コスト最適化
- ECS Fargate: 256 CPU, 2048 MBメモリ最小構成
- CloudWatch Logs: 7日間保持
- S3ライフサイクル: 7日間で古いアーティファクトを自動削除
## 監視とログ
### CloudWatch Logs
```bash
# ログストリーム確認
aws logs tail /ecs/clawdbot --follow
```
### ECSタスクの状態確認
```bash
# サービス状態
aws ecs describe-services --cluster clawdbot-cluster --services clawdbot-service
# タスク一覧
aws ecs list-tasks --cluster clawdbot-cluster
```
## トラブルシューティング
### コンテナが起動しない場合
1. CloudWatch Logsでエラーを確認
2. タスク定義の環境変数を確認
3. Secrets Managerからシークレットが取得できているか確認
### Discord Botが応答しない場合
1. ECSタスクが実行中か確認
2. セキュリティグループでアウトバウンド通信が許可されているか確認
3. Discord Bot Tokenが正しいか確認
## クリーンアップ
```bash
terraform destroy
```
注意: Secrets Managerのシークレットは手動で削除する必要があります:
```bash
aws secretsmanager delete-secret --secret-id clawdbot/discord-token
```

View File

@ -81,7 +81,7 @@ resource "aws_ecs_task_definition" "clawdbot" {
},
{
name = "DISCORD_BOT_TOKEN"
value = var.discord_token
value = data.aws_secretsmanager_secret_version.discord_token.secret_string
},
{
name = "CLAWDBOT_FORCE_BUILD"

View File

@ -81,3 +81,20 @@ resource "aws_iam_role_policy" "ecs_task_s3" {
]
})
}
# Task Role Policy: Secrets Manager access for Discord token
resource "aws_iam_role_policy" "ecs_task_secrets" {
name = "${var.project_name}-secrets-access"
role = aws_iam_role.ecs_task_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["secretsmanager:GetSecretValue"]
Resource = "arn:aws:secretsmanager:${var.aws_region}:${var.aws_account_id}:secret:${var.discord_token_secret_name}-??????*"
}
]
})
}

View File

@ -0,0 +1,8 @@
/**
* AWS Secrets Manager Data Sources
*/
# Discord Bot Token from Secrets Manager
data "aws_secretsmanager_secret_version" "discord_token" {
secret_id = var.discord_token_secret_name
}

View File

@ -4,6 +4,11 @@ variable "aws_region" {
default = "ap-northeast-1"
}
variable "aws_account_id" {
description = "AWS account ID (for Secrets Manager ARN)"
type = string
}
variable "environment" {
description = "Environment name (e.g., production, staging)"
type = string
@ -59,8 +64,16 @@ variable "ecs_service_desired_count" {
default = 1
}
variable "discord_token_secret_name" {
description = "AWS Secrets Manager secret name for Discord bot token"
type = string
default = "clawdbot/discord-token"
}
# DEPRECATED: Use discord_token_secret_name with AWS Secrets Manager instead
variable "discord_token" {
description = "Discord bot token (DISCORD_BOT_TOKEN) - sensitive, do not commit to version control"
description = "DEPRECATED: Discord bot token (use Secrets Manager instead)"
type = string
sensitive = true
default = null
}

View File

@ -3,9 +3,9 @@
* Discord bot requires outbound internet access for WebSocket connections
*/
# VPC
# VPC (using 100.64.0.0/16 to avoid conflicts with default 10.0.0.0/8)
resource "aws_vpc" "clawdbot" {
cidr_block = "10.0.0.0/16"
cidr_block = "100.64.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true