Repository navigation
refactor: K8s を削除し Terraform で DynamoDB + Auth0 を構築 - #118
Conversation
マイクロサービス構成からシンプルなモノレポ構成に移行: **apps/** - control-plane: テナント管理・認証(Next.js フルスタック) - application-plane: 競技者画面・バトル管理(Next.js フルスタック) - landing-site: ランディングページ **packages/** - core: AWS 連携、採点ロジック、共通型定義 - shared: 共通 UI コンポーネント **変更点:** - frontend/ → apps/ に移動 - admin-app と participant-app を application-plane に統合 - backend/services/application-plane/problem-service から packages/core にロジック抽出 - docker-compose.yml を簡素化(Keycloak 削除、DynamoDB local 追加) - Makefile を新構成に対応 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Keycloak から Auth0 に認証プロバイダーを切り替え: - auth.ts: Auth0 プロバイダーに変更 - カスタムクレーム(https://tenkacloud.com/roles)でロール取得 - ログインページ: Auth0 でログインボタンに更新 - 環境変数: AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, AUTH0_ISSUER - 型定義: Profile に Auth0 固有のクレームを追加 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Application Plane に競技者向けの認証機能を追加。 - NextAuth.js + Auth0 プロバイダによる認証を実装 - JWT コールバックで Auth0 カスタムクレームからテナント/チーム情報を取得 - AWS STS Federation による AWS Console へのシームレスなアクセス機能を追加 - 参加者用 Console Login URL 生成 (AssumeRole + Federation エンドポイント) - ログインページ UI を実装 - 包括的なテストを追加 (Auth0 認証設定、STS Federation) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- auth.test.ts: ロールフォールバックと session.user undefined のテスト追加 - tsconfig.json: .next フォルダを exclude に追加して型エラー回避 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## 変更内容 ### 削除 - Kubernetes マニフェスト (infrastructure/k8s/) - Keycloak 設定 (infrastructure/docker/keycloak/) - Cognito/EKS モジュールの .keep ファイル - docs/KUBERNETES.md ### 追加 - Terraform DynamoDB モジュール (Single Table Design) - PK/SK パターン - GSI1: 逆引きインデックス - GSI2: エンティティタイプ別リスト - PAY_PER_REQUEST 課金 - Terraform Auth0 モジュール - Control Plane / Application Plane アプリケーション - API Resource Server - スコープ定義 - Dev 環境設定 ### 修正 - Makefile から K8s 関連コマンドを削除 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WalkthroughThis PR removes Kubernetes manifests, Keycloak Docker Compose setup, and Kubernetes-centric Makefile targets, then introduces Terraform infrastructure-as-code for AWS DynamoDB and Auth0 configuration, shifting from container orchestration to cloud-native authentication and storage. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Areas requiring extra attention:
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Review: K8s を削除し Terraform で DynamoDB + Auth0 を構築🎯 総合評価この PR は、Kubernetes ベースの複雑なデプロイから、シンプルな Docker Compose + Terraform IaC へと大胆にシフトする優れたリファクタリングです。CLAUDE.md の Core Values「完全 OSS」「マルチクラウド」を維持しつつ、開発体験を大幅に向上させています。 推奨: マージ承認 ✅ ✅ 良い点1. アーキテクチャの簡素化
2. Infrastructure as Code の導入
3. セキュリティベストプラクティス
4. 再利用可能なモジュール設計
|
| 項目 | 状態 | 備考 |
|---|---|---|
make before-commit 実行 |
✅ | PR 説明に明記 |
| モックデータ禁止 | ✅ | Terraform で実リソース定義 |
| Ubiquitous Language | Role 定義が未実装(改善提案2参照) |
🚀 次のステップ提案
-
即座対応(マージ前):
- DynamoDB の
server_side_encryption追加 - Auth0 Role リソースを追加(または別 Issue 化)
- DynamoDB の
-
Follow-up Issue 推奨:
- DynamoDB アクセスパターン README 作成
- Terraform staging/prod 環境構築
- Auth0 MFA 設定(Production のみ)
🤖 最終判定
このPRは非常に高品質なリファクタリングです。 改善提案は「必須」ではなく「推奨」レベルであり、現状でもマージ可能です。
ただし、Auth0 Role 定義(改善提案2)だけは、CLAUDE.md の Ubiquitous Language との一貫性のため、早期対応を推奨します。
お疲れさまでした!🎉
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (12)
infrastructure/terraform/environments/dev/terraform.tfvars.example (1)
1-10: LGTM! Consider secrets management for production.The example file provides clear placeholders with a helpful warning. For production environments, consider using AWS Secrets Manager or similar instead of tfvars files for Auth0 credentials.
infrastructure/terraform/modules/dynamodb/main.tf (3)
48-64: Consider optimizing GSI projection types for cost efficiency.Both GSIs use
projection_type = "ALL", which replicates all item attributes into the index. This can significantly increase storage costs and write costs as the table grows. For the single-table design pattern, consider:
- Using
KEYS_ONLYif queries only need key attributes- Using
INCLUDEwith specific attributes if only a subset is neededFor PAY_PER_REQUEST mode, this also affects request costs since larger items consume more capacity.
🔎 Example: Optimized projection for GSI1
global_secondary_index { name = "GSI1" hash_key = "GSI1PK" range_key = "GSI1SK" - projection_type = "ALL" + projection_type = "INCLUDE" + non_key_attributes = ["EntityType", "CreatedAt"] # Include only necessary attributes }
43-46: Document CreatedAt format requirements for proper sorting.The
CreatedAtattribute is defined as type String and used as the range key in GSI2. For chronological sorting to work correctly, this attribute must use a sortable format such as ISO8601 (YYYY-MM-DDTHH:mm:ssZ) or Unix epoch timestamp. Consider documenting this requirement in comments or adding validation in application code.📝 Suggested documentation
attribute { name = "CreatedAt" type = "S" + # Must be ISO8601 format (e.g., 2025-12-19T00:00:00Z) for proper chronological sorting in GSI2 }
66-69: Document TTL attribute usage requirements.The TTL feature is enabled on the "TTL" attribute, but there's no documentation about how items should set this attribute. Consider adding a comment explaining that items must include a "TTL" attribute with a Unix epoch timestamp (in seconds) to enable automatic expiration.
📝 Suggested documentation
ttl { attribute_name = "TTL" enabled = true + # Items with a "TTL" attribute (Unix epoch in seconds) will be automatically deleted after expiration }infrastructure/terraform/environments/dev/main.tf (1)
7-29: Consider enabling remote backend for collaboration.The remote backend configuration is commented out. While local state is acceptable for individual development, consider enabling the S3 backend once the infrastructure stabilizes to enable team collaboration and state locking.
infrastructure/terraform/modules/dynamodb/variables.tf (1)
1-5: Consider removing the default table_name value.Having a default table name of "TenkaCloud" could lead to accidental name collisions if the variable isn't explicitly set per environment. Consider either:
- Removing the default to force explicit naming
- Using a more descriptive default like "TenkaCloud-changeme"
The dev environment correctly overrides this to "TenkaCloud-dev", which is good practice.
infrastructure/terraform/environments/dev/.terraform.lock.hcl (1)
26-47: AWS provider version is outdated; consider planning an upgrade to v6.x.The lockfile pins hashicorp/aws to v5.100.0, but the latest version is v6.26.0. While v6.0 of the Terraform AWS provider is now generally available with enhanced multi-region support and other workflow improvements, the constraint
~> 5.0deliberately prevents automatic upgrades to v6.x. No known security vulnerabilities have been documented for v5.100.0.infrastructure/terraform/environments/dev/variables.tf (1)
7-10: Add validation for Auth0 domain format.Consider adding validation to ensure the domain matches the expected Auth0 tenant domain pattern (e.g.,
dev-xxxxx.auth0.comor*.auth0.app).🔎 Suggested validation rule
variable "auth0_domain" { description = "Auth0 tenant domain (e.g., dev-xxxxx.auth0.com)" type = string + validation { + condition = can(regex("^[a-z0-9-]+\\.(auth0\\.com|auth0\\.app)$", var.auth0_domain)) + error_message = "The auth0_domain must be a valid Auth0 tenant domain (e.g., dev-xxxxx.auth0.com)." + } }infrastructure/terraform/modules/auth0/main.tf (2)
9-16: Consider pinning to a more specific Auth0 provider version.The version constraint
~> 1.0allows any 1.x version, which may introduce breaking changes. Consider using a more specific constraint like~> 1.5to reduce unexpected changes while still allowing patch updates.🔎 Suggested version constraint
required_providers { auth0 = { source = "auth0/auth0" - version = "~> 1.0" + version = "~> 1.5" } }
38-42: Consider token lifetime policy alignment and rotation effectiveness.Industry best practices typically recommend refresh token lifetimes of 7–14 days. However, Auth0's default refresh token expiration period is 30 days (2,592,000 seconds), and NIST SP 800-63B recommends that reauthentication overall timeout be no more than 30 days at AAL1.
Since your configuration has
rotation_type = "rotating"enabled, every time an application exchanges a refresh token to get a new access token, a new refresh token is also returned, and you no longer have a long-lived refresh token that, if compromised, could provide illegitimate access to resources. As refresh tokens are continually exchanged and invalidated, the threat surface area is greatly reduced.If stricter policy alignment is desired, consider reducing to 14 days or less, but verify that this aligns with your user experience expectations and actual threat model.
infrastructure/terraform/modules/auth0/variables.tf (2)
1-5: Add validation for API identifier format.Consider adding validation to ensure the API identifier is a valid HTTPS URL.
🔎 Suggested validation rule
variable "api_identifier" { description = "Identifier for the Auth0 API resource server" type = string default = "https://api.tenkacloud.com" + validation { + condition = can(regex("^https://", var.api_identifier)) + error_message = "The api_identifier must be a valid HTTPS URL." + } }
7-43: Document production URL requirements and consider validation.The localhost HTTP defaults are appropriate for local development. However, ensure that production environments override these with proper HTTPS URLs. Consider adding:
- A comment documenting that these must be overridden in production
- Validation rules to ensure URLs are properly formatted
🔎 Suggested documentation and validation
+# NOTE: The defaults below use localhost HTTP URLs for local development. +# Production environments MUST override these with HTTPS URLs. + # Control Plane URLs variable "control_plane_callbacks" { description = "Allowed callback URLs for Control Plane" type = list(string) default = ["http://localhost:3000/api/auth/callback/auth0"] + validation { + condition = alltrue([for url in var.control_plane_callbacks : can(regex("^https?://", url))]) + error_message = "All callback URLs must be valid HTTP or HTTPS URLs." + } }Apply similar validation to other URL variables.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (30)
Makefile(4 hunks)apps/application-plane/public/.gitkeep(1 hunks)docs/KUBERNETES.md(0 hunks)infrastructure/docker/keycloak/.env.example(0 hunks)infrastructure/docker/keycloak/.gitignore(0 hunks)infrastructure/docker/keycloak/README.md(0 hunks)infrastructure/docker/keycloak/docker-compose.yml(0 hunks)infrastructure/docker/keycloak/scripts/setup-keycloak.sh(0 hunks)infrastructure/k8s/application-plane/admin-app.yaml(0 hunks)infrastructure/k8s/application-plane/landing-site.yaml(0 hunks)infrastructure/k8s/application-plane/participant-app.yaml(0 hunks)infrastructure/k8s/base/keycloak.yaml(0 hunks)infrastructure/k8s/base/namespace.yaml(0 hunks)infrastructure/k8s/base/postgres-secret.yaml(0 hunks)infrastructure/k8s/base/postgres.yaml(0 hunks)infrastructure/k8s/base/secrets.yaml(0 hunks)infrastructure/k8s/control-plane/control-plane-ui.yaml(0 hunks)infrastructure/k8s/control-plane/tenant-management.yaml(0 hunks)infrastructure/terraform/.gitignore(1 hunks)infrastructure/terraform/environments/dev/.terraform.lock.hcl(1 hunks)infrastructure/terraform/environments/dev/main.tf(1 hunks)infrastructure/terraform/environments/dev/outputs.tf(1 hunks)infrastructure/terraform/environments/dev/terraform.tfvars.example(1 hunks)infrastructure/terraform/environments/dev/variables.tf(1 hunks)infrastructure/terraform/modules/auth0/main.tf(1 hunks)infrastructure/terraform/modules/auth0/outputs.tf(1 hunks)infrastructure/terraform/modules/auth0/variables.tf(1 hunks)infrastructure/terraform/modules/dynamodb/main.tf(1 hunks)infrastructure/terraform/modules/dynamodb/outputs.tf(1 hunks)infrastructure/terraform/modules/dynamodb/variables.tf(1 hunks)
💤 Files with no reviewable changes (16)
- infrastructure/docker/keycloak/scripts/setup-keycloak.sh
- infrastructure/docker/keycloak/README.md
- infrastructure/k8s/control-plane/control-plane-ui.yaml
- infrastructure/k8s/base/keycloak.yaml
- infrastructure/k8s/base/secrets.yaml
- infrastructure/k8s/control-plane/tenant-management.yaml
- infrastructure/docker/keycloak/.env.example
- infrastructure/k8s/base/postgres-secret.yaml
- infrastructure/k8s/base/postgres.yaml
- infrastructure/docker/keycloak/.gitignore
- infrastructure/k8s/application-plane/admin-app.yaml
- docs/KUBERNETES.md
- infrastructure/k8s/base/namespace.yaml
- infrastructure/docker/keycloak/docker-compose.yml
- infrastructure/k8s/application-plane/participant-app.yaml
- infrastructure/k8s/application-plane/landing-site.yaml
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-09T03:27:11.446Z
Learnt from: CR
Repo: susumutomita/TenkaCloud PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-09T03:27:11.446Z
Learning: TenkaCloud is a multi-tenant SaaS OSS cloud battle arena based on EKS Reference Architecture with support for AWS, GCP, Azure, LocalStack, and OCI
Applied to files:
infrastructure/terraform/environments/dev/main.tfinfrastructure/terraform/modules/auth0/main.tf
🪛 checkmake (0.2.2)
Makefile
[warning] 5-5: Missing required phony target "all"
(minphony)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: claude-review
- GitHub Check: ci
🔇 Additional comments (19)
apps/application-plane/public/.gitkeep (1)
1-2: No action needed.The
.gitkeepfile appropriately ensures this directory is tracked by Git. The Dockerfile correctly referencesapps/application-plane/public/during the Docker build process (copying it in the runner stage), confirming both comments are accurate and the file serves its intended purpose.Makefile (3)
199-201: LGTM! Simplified start/stop semantics align with K8s removal.The redirection of
startandstopto their Docker Compose variants appropriately reflects the infrastructure shift away from Kubernetes, simplifying the developer workflow.
383-384: LGTM! Help text accurately reflects the Docker Compose workflow.The updated help descriptions correctly document the new semantics of
startandstopcommands.
430-430: QUICKSTART.md already documents the new Docker Compose and Keycloak infrastructure, with no outdated Kubernetes references remaining. File is properly updated with comprehensive setup, configuration, and troubleshooting sections.infrastructure/terraform/.gitignore (1)
1-11: LGTM! Standard Terraform ignore patterns.The gitignore correctly excludes Terraform state files, working directories, variable files (while preserving examples), and override configurations.
infrastructure/terraform/modules/dynamodb/outputs.tf (1)
1-14: LGTM! Clean module outputs.The outputs expose all necessary DynamoDB table attributes for downstream consumption.
infrastructure/terraform/modules/dynamodb/main.tf (2)
12-16: LGTM! PAY_PER_REQUEST supports zero-cost operation.Using PAY_PER_REQUEST billing mode aligns with the PR objective of zero-cost operation for low-traffic environments.
1-11: Helpful PK/SK pattern documentation.The comment block clearly documents the single-table design patterns, which will help developers understand the schema structure.
infrastructure/terraform/environments/dev/main.tf (3)
31-41: LGTM! Well-configured AWS provider with default tags.The default tags (Project, Environment, ManagedBy) provide good resource tracking and align with AWS best practices.
50-59: LGTM! Cost-optimized DynamoDB configuration for dev.Disabling PITR for the dev environment is a reasonable cost optimization, and it's well-documented in the comment.
62-74: No action needed—Auth0 API identifiers don't require domain registration.The
api_identifiervalue is an Auth0 resource server identifier, not a registered domain. Auth0 uses it as a logical identifier to distinguish your API from others; Auth0 will not attempt to make any request to that URI. Using a domain-like format (e.g.,https://api.dev.tenkacloud.com) is a common convention for uniqueness but doesn't require actual domain registration. The localhost callback URLs are appropriate for local development.Likely an incorrect or invalid review comment.
infrastructure/terraform/environments/dev/outputs.tf (1)
1-24: LGTM! Appropriate outputs for downstream consumption.The outputs expose necessary identifiers while correctly omitting sensitive values like client secrets.
infrastructure/terraform/modules/dynamodb/variables.tf (1)
7-17: LGTM! Sensible defaults for PITR and tags.Enabling PITR by default is a good safety measure for production environments, while allowing it to be disabled (as done in dev) for cost optimization.
infrastructure/terraform/environments/dev/.terraform.lock.hcl (1)
4-24: No action needed—version 1.36.0 is the current latest release.Version 1.36.0 is marked as "Latest" and was released on November 19, 2025, making it recent and current. No known security issues exist for this version.
Likely an incorrect or invalid review comment.
infrastructure/terraform/environments/dev/variables.tf (2)
1-5: LGTM: AWS region configuration is correct.The default region
ap-northeast-1is appropriate and the variable is properly typed.
12-21: LGTM: Auth0 credentials are properly configured.The
auth0_client_secretis correctly marked as sensitive. The lack of default values for these credentials is good security practice, forcing explicit configuration.infrastructure/terraform/modules/auth0/outputs.tf (1)
1-26: LGTM: Auth0 module outputs are well-structured.The outputs correctly reference the Auth0 resources and properly mark sensitive values. The descriptions are clear and follow Terraform best practices.
infrastructure/terraform/modules/auth0/main.tf (2)
19-43: Auth0 configuration is well-structured with appropriate security settings.The configuration correctly implements:
- RS256 algorithm for JWT signing
- OIDC conformance
- Rotating refresh tokens with expiring tokens
- Appropriate grant types for web applications
- Well-defined API scopes for multi-tenant operations
The resource structure follows Auth0 and Terraform best practices for a multi-tenant SaaS platform.
Also applies to: 46-70, 73-110
113-122: Theclient_secret_postauthentication method is a valid and widely-used approach for Auth0 client credentials configuration. Bothclient_secret_postandclient_secret_basicare equally supported and secure methods for confidential applications. No change is required—this configuration aligns with Auth0 best practices and is compatible with NextAuth.js and server-to-server authentication flows. If stronger security is required, consider evaluatingprivate_key_jwtas an alternative.
| .PHONY: check-docker check-docker-hub check-k8s k8s-pull-base-images k8s-build-all k8s-deploy k8s-delete docker-build docker-run docker-stop docker-status | ||
| .PHONY: k8s-forward k8s-forward-stop k8s-start-full | ||
| .PHONY: check-docker check-docker-hub docker-build docker-run docker-stop docker-status | ||
| .PHONY: start-local stop-local logs-local test-lambda |
There was a problem hiding this comment.
Remove phony declarations for undefined targets.
The .PHONY declaration includes start-local, stop-local, logs-local, and test-lambda, but these targets are not defined anywhere in the Makefile. Declaring non-existent phony targets will cause make to fail with "No rule to make target" errors if invoked.
🔎 Proposed fix
Remove the undefined targets from the phony declaration:
-.PHONY: start-local stop-local logs-local test-lambdaIf these targets are planned for future implementation, ensure they are defined before declaring them as phony.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .PHONY: start-local stop-local logs-local test-lambda |
🧰 Tools
🪛 checkmake (0.2.2)
[warning] 5-5: Missing required phony target "all"
(minphony)
🤖 Prompt for AI Agents
In Makefile around line 5, the .PHONY declaration includes start-local,
stop-local, logs-local, and test-lambda which are not defined; remove those
undefined targets from the .PHONY list so only existing targets are declared
phony, or alternatively add proper target definitions for each if they are
intended to exist.
Summary
modules/dynamodb,modules/auth0)Test plan
terraform init成功terraform validate成功make before-commit全チェック通過🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.