@percepta/create 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -0
- package/dist/chunk-GEVZERMP.js +108 -0
- package/dist/chunk-R4FWPE4A.js +49 -0
- package/dist/chunk-WMJT7CB5.js +57 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +974 -0
- package/dist/init-Z4VGBHAK.js +96 -0
- package/dist/status-MITGDLTT.js +76 -0
- package/dist/sync-J4SFZHDX.js +136 -0
- package/dist/upstream-AQI7P4EU.js +144 -0
- package/package.json +58 -0
- package/template-versions.json +4 -0
- package/templates/library/README.md +30 -0
- package/templates/library/eslint.config.js +10 -0
- package/templates/library/gitignore.template +18 -0
- package/templates/library/package.json.template +29 -0
- package/templates/library/src/index.ts +9 -0
- package/templates/library/tsconfig.json +19 -0
- package/templates/monorepo/README.md +41 -0
- package/templates/monorepo/eslint.config.js +10 -0
- package/templates/monorepo/gitignore.template +31 -0
- package/templates/monorepo/npmrc.template +4 -0
- package/templates/monorepo/package.json.template +25 -0
- package/templates/monorepo/packages/.gitkeep +0 -0
- package/templates/monorepo/pnpm-workspace.yaml +2 -0
- package/templates/monorepo/tsconfig.json +16 -0
- package/templates/webapp/.claude/commands/sync.md +19 -0
- package/templates/webapp/.claude/commands/upstream.md +17 -0
- package/templates/webapp/.dockerignore +59 -0
- package/templates/webapp/.gitattributes +1 -0
- package/templates/webapp/.github/workflows/__APP_NAME__-ryvn-release.yaml +114 -0
- package/templates/webapp/.github/workflows/__APP_NAME__-terraform.yml +28 -0
- package/templates/webapp/.github/workflows/ci.yml +149 -0
- package/templates/webapp/.node-version +2 -0
- package/templates/webapp/.prettierrc.mjs +5 -0
- package/templates/webapp/AGENTS.md +240 -0
- package/templates/webapp/Dockerfile +64 -0
- package/templates/webapp/README.md +200 -0
- package/templates/webapp/agent-skills/database.md +140 -0
- package/templates/webapp/agent-skills/deploy.md +94 -0
- package/templates/webapp/agent-skills/inngest.md +147 -0
- package/templates/webapp/agent-skills/langfuse.md +117 -0
- package/templates/webapp/agent-skills/oneshot.md +216 -0
- package/templates/webapp/agent-skills/ryvn.md +25 -0
- package/templates/webapp/deploy/README.md +39 -0
- package/templates/webapp/deploy/ryvn/__APP_NAME__.service.yaml +11 -0
- package/templates/webapp/deploy/ryvn/environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml +121 -0
- package/templates/webapp/docker-compose.yml +19 -0
- package/templates/webapp/drizzle.config.ts +30 -0
- package/templates/webapp/env.example.template +44 -0
- package/templates/webapp/eslint.config.mjs +52 -0
- package/templates/webapp/gitignore.template +53 -0
- package/templates/webapp/next.config.ts +8 -0
- package/templates/webapp/npmrc.template +4 -0
- package/templates/webapp/package.json.template +122 -0
- package/templates/webapp/postcss.config.mjs +5 -0
- package/templates/webapp/scripts/create-user.ts +47 -0
- package/templates/webapp/scripts/migrate.ts +18 -0
- package/templates/webapp/scripts/seed.ts +62 -0
- package/templates/webapp/scripts/setup-database.ts +57 -0
- package/templates/webapp/scripts/setup-readonly-user.ts +193 -0
- package/templates/webapp/scripts/start.sh +52 -0
- package/templates/webapp/src/app/(app)/layout.tsx +21 -0
- package/templates/webapp/src/app/(app)/page.tsx +30 -0
- package/templates/webapp/src/app/(auth)/auth/signin/CredentialsSignInForm.tsx +103 -0
- package/templates/webapp/src/app/(auth)/auth/signin/page.tsx +30 -0
- package/templates/webapp/src/app/(auth)/layout.tsx +15 -0
- package/templates/webapp/src/app/api/auth/[...all]/route.ts +4 -0
- package/templates/webapp/src/app/api/healthz/route.ts +10 -0
- package/templates/webapp/src/app/api/inngest/route.ts +31 -0
- package/templates/webapp/src/app/api/readyz/route.ts +31 -0
- package/templates/webapp/src/app/api/trpc/[trpc]/route.ts +21 -0
- package/templates/webapp/src/app/favicon.ico +0 -0
- package/templates/webapp/src/app/global-error.tsx +27 -0
- package/templates/webapp/src/app/layout.tsx +18 -0
- package/templates/webapp/src/components/FaroProvider.tsx +37 -0
- package/templates/webapp/src/components/Header.tsx +70 -0
- package/templates/webapp/src/components/Providers.tsx +45 -0
- package/templates/webapp/src/components/form/FormItem.tsx +82 -0
- package/templates/webapp/src/config/clientEnvConfig.ts +11 -0
- package/templates/webapp/src/config/getEnvConfig.ts +62 -0
- package/templates/webapp/src/config/isDev.ts +7 -0
- package/templates/webapp/src/drizzle/db.ts +28 -0
- package/templates/webapp/src/drizzle/migrations/0000_eager_grandmaster.sql +57 -0
- package/templates/webapp/src/drizzle/migrations/meta/0000_snapshot.json +376 -0
- package/templates/webapp/src/drizzle/migrations/meta/_journal.json +13 -0
- package/templates/webapp/src/drizzle/schema/auth/accounts.ts +33 -0
- package/templates/webapp/src/drizzle/schema/auth/sessions.ts +25 -0
- package/templates/webapp/src/drizzle/schema/auth/users.ts +38 -0
- package/templates/webapp/src/drizzle/schema/auth/verifications.ts +19 -0
- package/templates/webapp/src/drizzle/schema/index.ts +4 -0
- package/templates/webapp/src/drizzle/schema/utils/jsonbFromZod.ts +25 -0
- package/templates/webapp/src/instrumentation.ts +35 -0
- package/templates/webapp/src/lib/auth/index.ts +85 -0
- package/templates/webapp/src/lib/auth-client.ts +6 -0
- package/templates/webapp/src/lib/trpc.ts +15 -0
- package/templates/webapp/src/server/api/root.ts +5 -0
- package/templates/webapp/src/server/trpc.ts +61 -0
- package/templates/webapp/src/services/AuthContextService.ts +63 -0
- package/templates/webapp/src/services/DatabaseService.ts +54 -0
- package/templates/webapp/src/services/inngest/InngestFunctionCollection.ts +5 -0
- package/templates/webapp/src/services/inngest/InngestService.ts +71 -0
- package/templates/webapp/src/services/inngest/events/AppEvents.ts +34 -0
- package/templates/webapp/src/services/inngest/events/payloads/ExampleEventPayload.ts +14 -0
- package/templates/webapp/src/services/langfuse/LangfuseService.ts +80 -0
- package/templates/webapp/src/services/logger/AppLogger.ts +61 -0
- package/templates/webapp/src/services/logger/withRequestContext.ts +27 -0
- package/templates/webapp/src/services/observability/initFaro.ts +22 -0
- package/templates/webapp/src/startup-checks.ts +32 -0
- package/templates/webapp/src/styles/globals.css +27 -0
- package/templates/webapp/src/utils/__tests__/cn.test.ts +20 -0
- package/templates/webapp/src/utils/cn.ts +6 -0
- package/templates/webapp/src/utils/syncInngestApp.ts +62 -0
- package/templates/webapp/terraform/README.md +147 -0
- package/templates/webapp/terraform/deploy.sh +97 -0
- package/templates/webapp/terraform/main.tf +101 -0
- package/templates/webapp/terraform/modules/cloudtrail/main.tf +27 -0
- package/templates/webapp/terraform/modules/cloudtrail/outputs.tf +10 -0
- package/templates/webapp/terraform/modules/cloudtrail/variables.tf +15 -0
- package/templates/webapp/terraform/modules/networking/main.tf +118 -0
- package/templates/webapp/terraform/modules/networking/outputs.tf +38 -0
- package/templates/webapp/terraform/modules/networking/variables.tf +24 -0
- package/templates/webapp/terraform/modules/rds/main.tf +227 -0
- package/templates/webapp/terraform/modules/rds/outputs.tf +73 -0
- package/templates/webapp/terraform/modules/rds/variables.tf +61 -0
- package/templates/webapp/terraform/modules/s3-logging/main.tf +148 -0
- package/templates/webapp/terraform/modules/s3-logging/outputs.tf +10 -0
- package/templates/webapp/terraform/modules/s3-logging/variables.tf +16 -0
- package/templates/webapp/terraform/modules/secrets/main.tf +39 -0
- package/templates/webapp/terraform/modules/secrets/outputs.tf +9 -0
- package/templates/webapp/terraform/modules/secrets/variables.tf +51 -0
- package/templates/webapp/terraform/outputs.tf +102 -0
- package/templates/webapp/terraform/providers.tf +32 -0
- package/templates/webapp/terraform/terraform.tfvars.example +65 -0
- package/templates/webapp/terraform/variables.tf +129 -0
- package/templates/webapp/tsconfig.json +14 -0
- package/templates/webapp/vitest.config.ts +9 -0
- package/templates/webapp/vitest.setup.ts +5 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# __APP_NAME_UPPER__ Terraform Service
|
|
2
|
+
|
|
3
|
+
This Terraform service creates AWS infrastructure for the __APP_NAME_UPPER__ system.
|
|
4
|
+
|
|
5
|
+
## Architecture Overview
|
|
6
|
+
|
|
7
|
+
The service creates the following components:
|
|
8
|
+
|
|
9
|
+
### 1. RDS Module
|
|
10
|
+
- **Flexible RDS**: Can use existing cluster or create new Aurora PostgreSQL cluster
|
|
11
|
+
- **Database**: `__DB_NAME__` database
|
|
12
|
+
- **User**: `__APP_NAME__-db-user` with access to the database
|
|
13
|
+
- **Security**: Proper VPC security groups and SSL certificates
|
|
14
|
+
|
|
15
|
+
### 3. Secrets Module
|
|
16
|
+
- **EKS Secrets**: All credentials stored as Kubernetes secrets:
|
|
17
|
+
- `__APP_NAME__-database-credentials`
|
|
18
|
+
|
|
19
|
+
### 4. Networking Module
|
|
20
|
+
- **VPC Integration**: Works with existing VPC and subnets
|
|
21
|
+
- **Security Groups**: Proper network access controls
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Required Variables
|
|
26
|
+
|
|
27
|
+
```hcl
|
|
28
|
+
# Basic configuration
|
|
29
|
+
environment = "prod"
|
|
30
|
+
name = "__APP_NAME__"
|
|
31
|
+
region = "us-west-2"
|
|
32
|
+
|
|
33
|
+
# EKS configuration
|
|
34
|
+
cluster_name = "my-eks-cluster"
|
|
35
|
+
vpc_id = "vpc-12345678"
|
|
36
|
+
|
|
37
|
+
# Optional: Use existing RDS cluster
|
|
38
|
+
existing_rds_cluster_name = "existing-cluster-name"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Optional Variables
|
|
42
|
+
|
|
43
|
+
```hcl
|
|
44
|
+
# Kubernetes namespace (default: "__APP_NAME__")
|
|
45
|
+
namespace = "__APP_NAME__"
|
|
46
|
+
|
|
47
|
+
# Subnet configuration (auto-discovered if not provided)
|
|
48
|
+
subnet_ids = ["subnet-12345", "subnet-67890"]
|
|
49
|
+
|
|
50
|
+
# RDS configuration
|
|
51
|
+
create_new_rds = true
|
|
52
|
+
rds_engine_version = "16.8"
|
|
53
|
+
rds_port = 5432
|
|
54
|
+
|
|
55
|
+
# S3 lifecycle
|
|
56
|
+
s3_bucket_expiration_days = 90
|
|
57
|
+
|
|
58
|
+
# Readonly database access (optional - for external data warehouse access)
|
|
59
|
+
edw_allowed_principals = ["arn:aws:iam::123456789012:role/ExampleRole"]
|
|
60
|
+
edw_vpc_cidr_blocks = ["10.20.0.0/16"]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Readonly Database Access
|
|
64
|
+
|
|
65
|
+
The infrastructure optionally creates a readonly database user for external data access (e.g., data warehouses, analytics platforms). When `edw_allowed_principals` is configured:
|
|
66
|
+
|
|
67
|
+
- A readonly database user is created with `SELECT`-only access
|
|
68
|
+
- Credentials are stored in AWS Secrets Manager
|
|
69
|
+
- An IAM role is created that specified principals can assume to read the credentials
|
|
70
|
+
- Security group rules allow traffic from specified VPC CIDR blocks
|
|
71
|
+
|
|
72
|
+
Configure `edw_allowed_principals` and `edw_vpc_cidr_blocks` in your `terraform.tfvars` to enable this feature. See the Terraform outputs for the secret ARN and reader role ARN needed to connect.
|
|
73
|
+
|
|
74
|
+
## Deployment
|
|
75
|
+
|
|
76
|
+
1. **Initialize Terraform**:
|
|
77
|
+
```bash
|
|
78
|
+
terraform init
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
2. **Plan deployment**:
|
|
82
|
+
```bash
|
|
83
|
+
terraform plan -var-file="terraform.tfvars"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
3. **Apply configuration**:
|
|
87
|
+
```bash
|
|
88
|
+
terraform apply -var-file="terraform.tfvars"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Outputs
|
|
92
|
+
|
|
93
|
+
The service provides comprehensive outputs for integration:
|
|
94
|
+
|
|
95
|
+
### Database Outputs
|
|
96
|
+
- `rds_cluster_endpoint`: Database endpoint
|
|
97
|
+
- `rds_database_name`: Database name
|
|
98
|
+
- `database_secret_name`: Kubernetes secret name
|
|
99
|
+
|
|
100
|
+
## Security Features
|
|
101
|
+
|
|
102
|
+
- **Encryption**: All S3 buckets enforce encryption in transit
|
|
103
|
+
- **IAM**: Least-privilege access policies
|
|
104
|
+
- **Network**: VPC-based security groups
|
|
105
|
+
- **Secrets**: Sensitive data stored in AWS Secrets Manager and Kubernetes secrets
|
|
106
|
+
- **SSL**: Database connections use SSL certificates
|
|
107
|
+
|
|
108
|
+
## Prerequisites
|
|
109
|
+
|
|
110
|
+
- AWS CLI configured with appropriate permissions
|
|
111
|
+
- kubectl configured for target EKS cluster
|
|
112
|
+
- Terraform >= 1.9.8
|
|
113
|
+
- Existing VPC and EKS cluster
|
|
114
|
+
|
|
115
|
+
## Permissions Required
|
|
116
|
+
|
|
117
|
+
The deploying user/role needs permissions for:
|
|
118
|
+
- IAM user and policy management
|
|
119
|
+
- S3 bucket creation and management
|
|
120
|
+
- RDS cluster management (if creating new)
|
|
121
|
+
- Kubernetes secret management
|
|
122
|
+
- VPC and networking resources
|
|
123
|
+
|
|
124
|
+
## Notes
|
|
125
|
+
|
|
126
|
+
- **Database User Creation**: The RDS module creates the password and stores it securely, but actual database user creation may need to be handled through initialization scripts or database providers.
|
|
127
|
+
- **Cost Optimization**: S3 lifecycle policies are configured to expire objects after the specified number of days.
|
|
128
|
+
|
|
129
|
+
## Troubleshooting
|
|
130
|
+
|
|
131
|
+
### Common Issues
|
|
132
|
+
|
|
133
|
+
1. **VPC Subnets**: Verify subnets have the correct tags for auto-discovery
|
|
134
|
+
2. **EKS Permissions**: Ensure Terraform has permissions to create Kubernetes resources
|
|
135
|
+
3. **RDS Existing Cluster**: Verify the existing cluster name is correct and accessible
|
|
136
|
+
|
|
137
|
+
### Validation
|
|
138
|
+
|
|
139
|
+
Run `terraform validate` to check configuration syntax:
|
|
140
|
+
```bash
|
|
141
|
+
terraform validate
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Run `terraform plan` to preview changes before applying:
|
|
145
|
+
```bash
|
|
146
|
+
terraform plan
|
|
147
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# __APP_NAME_UPPER__ Terraform Deployment Script
|
|
4
|
+
# This script helps deploy the __APP_NAME_UPPER__ infrastructure
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Colors for output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
NC='\033[0m' # No Color
|
|
13
|
+
|
|
14
|
+
# Function to print colored output
|
|
15
|
+
print_status() {
|
|
16
|
+
echo -e "${GREEN}[INFO]${NC} $1"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
print_warning() {
|
|
20
|
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
print_error() {
|
|
24
|
+
echo -e "${RED}[ERROR]${NC} $1"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# Check if terraform.tfvars exists
|
|
28
|
+
if [ ! -f "terraform.tfvars" ]; then
|
|
29
|
+
print_error "terraform.tfvars not found!"
|
|
30
|
+
print_status "Please copy terraform.tfvars.example to terraform.tfvars and customize it for your environment."
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Check if required tools are installed
|
|
35
|
+
command -v terraform >/dev/null 2>&1 || { print_error "terraform is required but not installed. Aborting."; exit 1; }
|
|
36
|
+
command -v kubectl >/dev/null 2>&1 || { print_error "kubectl is required but not installed. Aborting."; exit 1; }
|
|
37
|
+
command -v aws >/dev/null 2>&1 || { print_error "aws CLI is required but not installed. Aborting."; exit 1; }
|
|
38
|
+
|
|
39
|
+
# Parse command line arguments
|
|
40
|
+
ACTION=${1:-plan}
|
|
41
|
+
|
|
42
|
+
case $ACTION in
|
|
43
|
+
init)
|
|
44
|
+
print_status "Initializing Terraform..."
|
|
45
|
+
terraform init
|
|
46
|
+
;;
|
|
47
|
+
plan)
|
|
48
|
+
print_status "Planning Terraform deployment..."
|
|
49
|
+
terraform plan -var-file="terraform.tfvars"
|
|
50
|
+
;;
|
|
51
|
+
apply)
|
|
52
|
+
print_status "Applying Terraform configuration..."
|
|
53
|
+
print_warning "This will create/modify AWS resources. Continue? (y/N)"
|
|
54
|
+
read -r response
|
|
55
|
+
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
|
56
|
+
terraform apply -var-file="terraform.tfvars"
|
|
57
|
+
print_status "Deployment completed successfully!"
|
|
58
|
+
print_status "Check the outputs above for important resource information."
|
|
59
|
+
else
|
|
60
|
+
print_status "Deployment cancelled."
|
|
61
|
+
fi
|
|
62
|
+
;;
|
|
63
|
+
destroy)
|
|
64
|
+
print_warning "This will DESTROY all __APP_NAME_UPPER__ infrastructure!"
|
|
65
|
+
print_warning "Are you absolutely sure? Type 'yes' to continue:"
|
|
66
|
+
read -r response
|
|
67
|
+
if [[ "$response" == "yes" ]]; then
|
|
68
|
+
terraform destroy -var-file="terraform.tfvars"
|
|
69
|
+
print_status "Infrastructure destroyed."
|
|
70
|
+
else
|
|
71
|
+
print_status "Destruction cancelled."
|
|
72
|
+
fi
|
|
73
|
+
;;
|
|
74
|
+
validate)
|
|
75
|
+
print_status "Validating Terraform configuration..."
|
|
76
|
+
terraform validate
|
|
77
|
+
print_status "Configuration is valid!"
|
|
78
|
+
;;
|
|
79
|
+
output)
|
|
80
|
+
print_status "Showing Terraform outputs..."
|
|
81
|
+
terraform output
|
|
82
|
+
;;
|
|
83
|
+
*)
|
|
84
|
+
echo "Usage: $0 {init|plan|apply|destroy|validate|output}"
|
|
85
|
+
echo ""
|
|
86
|
+
echo "Commands:"
|
|
87
|
+
echo " init - Initialize Terraform (run this first)"
|
|
88
|
+
echo " plan - Show what changes will be made"
|
|
89
|
+
echo " apply - Apply the Terraform configuration"
|
|
90
|
+
echo " destroy - Destroy all infrastructure (DANGEROUS)"
|
|
91
|
+
echo " validate - Validate the Terraform configuration"
|
|
92
|
+
echo " output - Show current outputs"
|
|
93
|
+
echo ""
|
|
94
|
+
echo "Example: $0 plan"
|
|
95
|
+
exit 1
|
|
96
|
+
;;
|
|
97
|
+
esac
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
data "aws_eks_cluster" "cluster" {
|
|
2
|
+
name = var.cluster_name
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
data "aws_iam_openid_connect_provider" "cluster_oidc_provider" {
|
|
6
|
+
url = data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
################################################################################
|
|
10
|
+
# IAM Role for Application Service Account
|
|
11
|
+
################################################################################
|
|
12
|
+
|
|
13
|
+
data "aws_iam_policy_document" "app_assume_role_policy" {
|
|
14
|
+
statement {
|
|
15
|
+
actions = ["sts:AssumeRoleWithWebIdentity"]
|
|
16
|
+
|
|
17
|
+
principals {
|
|
18
|
+
type = "Federated"
|
|
19
|
+
identifiers = [data.aws_iam_openid_connect_provider.cluster_oidc_provider.arn]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
condition {
|
|
23
|
+
test = "StringEquals"
|
|
24
|
+
variable = "${trimsuffix(replace(data.aws_iam_openid_connect_provider.cluster_oidc_provider.url, "https://", ""), "/")}:sub"
|
|
25
|
+
values = ["system:serviceaccount:${var.namespace}:${var.kubernetes_service_account}"]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
condition {
|
|
29
|
+
test = "StringEquals"
|
|
30
|
+
variable = "${trimsuffix(replace(data.aws_iam_openid_connect_provider.cluster_oidc_provider.url, "https://", ""), "/")}:aud"
|
|
31
|
+
values = ["sts.amazonaws.com"]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
resource "aws_iam_role" "app_service_account_role" {
|
|
37
|
+
name = "__APP_NAME_UPPER__-App-Role-${var.name}-${var.environment}"
|
|
38
|
+
assume_role_policy = data.aws_iam_policy_document.app_assume_role_policy.json
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# Networking Module - Get VPC and subnet information
|
|
42
|
+
module "networking" {
|
|
43
|
+
source = "./modules/networking"
|
|
44
|
+
|
|
45
|
+
vpc_id = var.vpc_id
|
|
46
|
+
subnet_ids = var.subnet_ids
|
|
47
|
+
subnet_tags = var.subnet_tags
|
|
48
|
+
ingress_cidr_blocks = var.ingress_cidr_blocks
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# RDS Module - Create or use existing RDS cluster
|
|
52
|
+
module "rds" {
|
|
53
|
+
source = "./modules/rds"
|
|
54
|
+
|
|
55
|
+
name = var.name
|
|
56
|
+
environment = var.environment
|
|
57
|
+
existing_cluster_name = var.existing_rds_cluster_name
|
|
58
|
+
create_new_cluster = var.create_new_rds
|
|
59
|
+
vpc_id = var.vpc_id
|
|
60
|
+
subnet_ids = module.networking.subnet_ids
|
|
61
|
+
engine_version = var.rds_engine_version
|
|
62
|
+
port = var.rds_port
|
|
63
|
+
instance_class = var.rds_instance_class
|
|
64
|
+
edw_allowed_principals = var.edw_allowed_principals
|
|
65
|
+
edw_vpc_cidr_blocks = var.edw_vpc_cidr_blocks
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# S3 Logging Module - Create S3 bucket for access logs
|
|
69
|
+
module "s3_logging" {
|
|
70
|
+
source = "./modules/s3-logging"
|
|
71
|
+
|
|
72
|
+
name = var.name
|
|
73
|
+
environment = var.environment
|
|
74
|
+
s3_expiration_days = var.s3_bucket_expiration_days
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# CloudTrail Module - Create CloudTrail trail for S3 data event logging
|
|
78
|
+
module "cloudtrail" {
|
|
79
|
+
source = "./modules/cloudtrail"
|
|
80
|
+
|
|
81
|
+
name = var.name
|
|
82
|
+
environment = var.environment
|
|
83
|
+
logging_bucket_name = module.s3_logging.s3_bucket_name
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Secrets Module - Create EKS secrets for all credentials
|
|
87
|
+
module "secrets" {
|
|
88
|
+
source = "./modules/secrets"
|
|
89
|
+
|
|
90
|
+
namespace = var.namespace
|
|
91
|
+
cluster_name = var.cluster_name
|
|
92
|
+
|
|
93
|
+
# Database credentials
|
|
94
|
+
db_host = module.rds.host
|
|
95
|
+
db_port = module.rds.port
|
|
96
|
+
db_name = module.rds.database_name
|
|
97
|
+
db_username = module.rds.username
|
|
98
|
+
db_password = module.rds.password
|
|
99
|
+
db_ssl_cert = module.rds.ssl_cert
|
|
100
|
+
db_url = module.rds.connection_url
|
|
101
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
################################################################################
|
|
2
|
+
# CloudTrail Trail
|
|
3
|
+
################################################################################
|
|
4
|
+
|
|
5
|
+
# Note: The S3 bucket policy for CloudTrail is managed in the s3-logging module
|
|
6
|
+
# to avoid conflicts with multiple bucket policy resources
|
|
7
|
+
resource "aws_cloudtrail" "trail" {
|
|
8
|
+
name = "${var.name}-trail-${var.environment}"
|
|
9
|
+
s3_bucket_name = var.logging_bucket_name
|
|
10
|
+
s3_key_prefix = "cloudtrail/"
|
|
11
|
+
include_global_service_events = true
|
|
12
|
+
is_multi_region_trail = true
|
|
13
|
+
enable_logging = true
|
|
14
|
+
enable_log_file_validation = true
|
|
15
|
+
|
|
16
|
+
event_selector {
|
|
17
|
+
read_write_type = "All"
|
|
18
|
+
include_management_events = true
|
|
19
|
+
exclude_management_event_sources = []
|
|
20
|
+
|
|
21
|
+
data_resource {
|
|
22
|
+
type = "AWS::S3::Object"
|
|
23
|
+
values = ["arn:aws:s3"]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
variable "name" {
|
|
2
|
+
description = "Base name for resources"
|
|
3
|
+
type = string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "environment" {
|
|
7
|
+
description = "Environment name (e.g. dev, staging, prod)"
|
|
8
|
+
type = string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "logging_bucket_name" {
|
|
12
|
+
description = "Name of the S3 bucket to store CloudTrail logs"
|
|
13
|
+
type = string
|
|
14
|
+
}
|
|
15
|
+
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
data "aws_vpc" "vpc" {
|
|
2
|
+
id = var.vpc_id
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
# Get the private subnets assigned to the vpc
|
|
6
|
+
data "aws_subnets" "subnets" {
|
|
7
|
+
filter {
|
|
8
|
+
name = "vpc-id"
|
|
9
|
+
values = [data.aws_vpc.vpc.id]
|
|
10
|
+
}
|
|
11
|
+
tags = var.subnet_tags
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
data "aws_subnet" "subnet" {
|
|
15
|
+
count = length(local.subnet_ids)
|
|
16
|
+
id = local.subnet_ids[count.index]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
locals {
|
|
20
|
+
subnet_ids = var.subnet_ids != null ? var.subnet_ids : data.aws_subnets.subnets.ids
|
|
21
|
+
vpc_cidr = data.aws_vpc.vpc.cidr_block
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
################################################################################
|
|
25
|
+
# Security Group for VPC Endpoints
|
|
26
|
+
################################################################################
|
|
27
|
+
|
|
28
|
+
resource "aws_security_group" "vpc_endpoints" {
|
|
29
|
+
name_prefix = "__APP_NAME__-vpc-endpoints-"
|
|
30
|
+
vpc_id = data.aws_vpc.vpc.id
|
|
31
|
+
description = "Security group for __APP_NAME_UPPER__ VPC endpoints"
|
|
32
|
+
|
|
33
|
+
ingress {
|
|
34
|
+
description = "HTTPS from VPC"
|
|
35
|
+
from_port = 443
|
|
36
|
+
to_port = 443
|
|
37
|
+
protocol = "tcp"
|
|
38
|
+
cidr_blocks = [data.aws_vpc.vpc.cidr_block]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
egress {
|
|
42
|
+
description = "All outbound traffic"
|
|
43
|
+
from_port = 0
|
|
44
|
+
to_port = 0
|
|
45
|
+
protocol = "-1"
|
|
46
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
tags = {
|
|
50
|
+
Name = "__APP_NAME__-vpc-endpoints"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
################################################################################
|
|
55
|
+
# VPC Endpoints for AWS Services
|
|
56
|
+
################################################################################
|
|
57
|
+
|
|
58
|
+
# S3 VPC Endpoint (Gateway type for better performance and cost)
|
|
59
|
+
resource "aws_vpc_endpoint" "s3" {
|
|
60
|
+
vpc_id = data.aws_vpc.vpc.id
|
|
61
|
+
service_name = "com.amazonaws.${data.aws_region.current.name}.s3"
|
|
62
|
+
|
|
63
|
+
policy = jsonencode({
|
|
64
|
+
Version = "2012-10-17"
|
|
65
|
+
Statement = [
|
|
66
|
+
{
|
|
67
|
+
Effect = "Allow"
|
|
68
|
+
Principal = "*"
|
|
69
|
+
Action = [
|
|
70
|
+
"s3:GetObject",
|
|
71
|
+
"s3:PutObject",
|
|
72
|
+
"s3:DeleteObject",
|
|
73
|
+
"s3:ListBucket"
|
|
74
|
+
]
|
|
75
|
+
Resource = "*"
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
tags = {
|
|
81
|
+
Name = "__APP_NAME__-s3-endpoint"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Get current AWS region
|
|
86
|
+
data "aws_region" "current" {}
|
|
87
|
+
|
|
88
|
+
################################################################################
|
|
89
|
+
# Security Group for Ingress CIDR blocks
|
|
90
|
+
################################################################################
|
|
91
|
+
|
|
92
|
+
resource "aws_security_group" "ingress" {
|
|
93
|
+
for_each = var.ingress_cidr_blocks
|
|
94
|
+
|
|
95
|
+
name_prefix = "__APP_NAME__-${each.key}-"
|
|
96
|
+
vpc_id = data.aws_vpc.vpc.id
|
|
97
|
+
description = "Security group for ${each.key}"
|
|
98
|
+
|
|
99
|
+
ingress {
|
|
100
|
+
description = "All TCP from specified CIDRs"
|
|
101
|
+
from_port = 0
|
|
102
|
+
to_port = 65535
|
|
103
|
+
protocol = "tcp"
|
|
104
|
+
cidr_blocks = each.value
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
egress {
|
|
108
|
+
description = "All outbound traffic"
|
|
109
|
+
from_port = 0
|
|
110
|
+
to_port = 0
|
|
111
|
+
protocol = "-1"
|
|
112
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
tags = {
|
|
116
|
+
Name = "__APP_NAME__-${each.key}"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
output "vpc_id" {
|
|
2
|
+
description = "VPC ID"
|
|
3
|
+
value = data.aws_vpc.vpc.id
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "vpc_cidr" {
|
|
7
|
+
description = "VPC CIDR block"
|
|
8
|
+
value = local.vpc_cidr
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
output "subnet_ids" {
|
|
12
|
+
description = "List of subnet IDs"
|
|
13
|
+
value = local.subnet_ids
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
output "availability_zones" {
|
|
17
|
+
description = "List of availability zones for the subnets"
|
|
18
|
+
value = data.aws_subnet.subnet[*].availability_zone
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
################################################################################
|
|
22
|
+
# VPC Endpoint Outputs
|
|
23
|
+
################################################################################
|
|
24
|
+
|
|
25
|
+
output "vpc_endpoint_security_group_id" {
|
|
26
|
+
description = "Security group ID for VPC endpoints"
|
|
27
|
+
value = aws_security_group.vpc_endpoints.id
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
output "s3_vpc_endpoint_id" {
|
|
31
|
+
description = "S3 VPC endpoint ID"
|
|
32
|
+
value = aws_vpc_endpoint.s3.id
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
output "ingress_cidr_blocks" {
|
|
36
|
+
description = "Map of dynamically created security groups for ingress"
|
|
37
|
+
value = aws_security_group.ingress
|
|
38
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
variable "vpc_id" {
|
|
2
|
+
description = "VPC ID where resources will be deployed"
|
|
3
|
+
type = string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "subnet_ids" {
|
|
7
|
+
description = "List of subnet IDs for resources"
|
|
8
|
+
type = list(string)
|
|
9
|
+
default = null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
variable "subnet_tags" {
|
|
13
|
+
description = "Tags for subnet selection"
|
|
14
|
+
type = map(string)
|
|
15
|
+
default = {
|
|
16
|
+
"kubernetes.io/role/internal-elb" = "1"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
variable "ingress_cidr_blocks" {
|
|
21
|
+
description = "A map of security group names to a list of CIDR blocks to allow access from."
|
|
22
|
+
type = map(list(string))
|
|
23
|
+
default = {}
|
|
24
|
+
}
|