@percepta/create 3.6.1 → 3.6.3

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.
Files changed (83) hide show
  1. package/README.md +37 -6
  2. package/dist/{git-ops-C2CIjuce.js → git-ops-BD7JNnal.js} +1 -1
  3. package/dist/{git-ops-C2CIjuce.js.map → git-ops-BD7JNnal.js.map} +1 -1
  4. package/dist/github-RCIMUq70.js +131 -0
  5. package/dist/github-RCIMUq70.js.map +1 -0
  6. package/dist/index.js +63 -122
  7. package/dist/index.js.map +1 -1
  8. package/dist/{init-sI9aIrkU.js → init-COp0nGdk.js} +4 -2
  9. package/dist/{init-sI9aIrkU.js.map → init-COp0nGdk.js.map} +1 -1
  10. package/dist/manifest-CqIDnbgs.js +58 -0
  11. package/dist/manifest-CqIDnbgs.js.map +1 -0
  12. package/dist/register-app-C7ZBpAaZ.js +103 -0
  13. package/dist/register-app-C7ZBpAaZ.js.map +1 -0
  14. package/dist/register-os-blueprint-DGjBUZYa.js +90 -0
  15. package/dist/register-os-blueprint-DGjBUZYa.js.map +1 -0
  16. package/dist/{status-CKe4aKso.js → status-BXYaQ4a2.js} +3 -3
  17. package/dist/{status-CKe4aKso.js.map → status-BXYaQ4a2.js.map} +1 -1
  18. package/dist/{sync-D1vkoofl.js → sync-BayU4w1j.js} +3 -3
  19. package/dist/{sync-D1vkoofl.js.map → sync-BayU4w1j.js.map} +1 -1
  20. package/dist/template-versions-CEIP9vhl.js +35 -0
  21. package/dist/template-versions-CEIP9vhl.js.map +1 -0
  22. package/dist/{upstream-gUHLWSR1.js → upstream-CZEzLrS4.js} +3 -3
  23. package/dist/{upstream-gUHLWSR1.js.map → upstream-CZEzLrS4.js.map} +1 -1
  24. package/dist/validate-dssldJAj.js +14 -0
  25. package/dist/validate-dssldJAj.js.map +1 -0
  26. package/package.json +1 -1
  27. package/template-versions.json +2 -2
  28. package/templates/infra/os.blueprint.yaml.template +138 -0
  29. package/templates/monorepo/README.md +41 -3
  30. package/templates/monorepo/auth/README.md +6 -3
  31. package/templates/monorepo/auth/package.json +2 -4
  32. package/templates/monorepo/auth/src/config/database.ts +1 -1
  33. package/templates/{webapp → monorepo}/docker-compose.yml +2 -2
  34. package/templates/monorepo/package.json.template +5 -2
  35. package/templates/monorepo/pnpm-workspace.yaml +4 -0
  36. package/templates/monorepo/scripts/setup-local-databases.mjs +183 -0
  37. package/templates/webapp/AGENTS.md +13 -20
  38. package/templates/webapp/README.md +32 -36
  39. package/templates/webapp/agent-skills/database.md +21 -21
  40. package/templates/webapp/agent-skills/langfuse.md +7 -7
  41. package/templates/webapp/agent-skills/llm.md +4 -2
  42. package/templates/webapp/agent-skills/oneshot.md +7 -6
  43. package/templates/webapp/agent-skills/ryvn.md +12 -16
  44. package/templates/webapp/deploy/README.md +10 -51
  45. package/templates/webapp/drizzle.config.ts +2 -23
  46. package/templates/webapp/env.example.template +8 -14
  47. package/templates/webapp/package.json.template +8 -15
  48. package/templates/webapp/scripts/start.sh +12 -16
  49. package/templates/webapp/src/config/getEnvConfig.ts +4 -10
  50. package/templates/webapp/src/drizzle/db.ts +6 -21
  51. package/templates/webapp/src/startup-checks.ts +28 -7
  52. package/templates/monorepo/auth/scripts/setup-database.ts +0 -11
  53. package/templates/webapp/.github/workflows/__APP_NAME__-terraform-ryvn-release.yaml +0 -92
  54. package/templates/webapp/agent-skills/deploy.md +0 -92
  55. package/templates/webapp/deploy/ryvn/__APP_NAME__-terraform.service.yaml +0 -10
  56. package/templates/webapp/deploy/ryvn/environments/percepta-test/installations/__APP_NAME__-terraform.env.percepta-test.serviceinstallation.yaml +0 -11
  57. package/templates/webapp/deploy/ryvn/environments/percepta-test/installations/__APP_NAME__.env.percepta-test.serviceinstallation.yaml +0 -154
  58. package/templates/webapp/terraform/README.md +0 -147
  59. package/templates/webapp/terraform/deploy.sh +0 -97
  60. package/templates/webapp/terraform/main.tf +0 -101
  61. package/templates/webapp/terraform/modules/cloudtrail/main.tf +0 -27
  62. package/templates/webapp/terraform/modules/cloudtrail/outputs.tf +0 -10
  63. package/templates/webapp/terraform/modules/cloudtrail/variables.tf +0 -15
  64. package/templates/webapp/terraform/modules/networking/main.tf +0 -118
  65. package/templates/webapp/terraform/modules/networking/outputs.tf +0 -38
  66. package/templates/webapp/terraform/modules/networking/variables.tf +0 -24
  67. package/templates/webapp/terraform/modules/rds/main.tf +0 -227
  68. package/templates/webapp/terraform/modules/rds/outputs.tf +0 -73
  69. package/templates/webapp/terraform/modules/rds/variables.tf +0 -61
  70. package/templates/webapp/terraform/modules/s3-logging/main.tf +0 -148
  71. package/templates/webapp/terraform/modules/s3-logging/outputs.tf +0 -10
  72. package/templates/webapp/terraform/modules/s3-logging/variables.tf +0 -16
  73. package/templates/webapp/terraform/modules/secrets/main.tf +0 -39
  74. package/templates/webapp/terraform/modules/secrets/outputs.tf +0 -9
  75. package/templates/webapp/terraform/modules/secrets/variables.tf +0 -51
  76. package/templates/webapp/terraform/outputs.tf +0 -102
  77. package/templates/webapp/terraform/providers.tf +0 -32
  78. package/templates/webapp/terraform/schema/main.tf +0 -4
  79. package/templates/webapp/terraform/schema/outputs.tf +0 -9
  80. package/templates/webapp/terraform/schema/variables.tf +0 -19
  81. package/templates/webapp/terraform/schema/versions.tf +0 -38
  82. package/templates/webapp/terraform/terraform.tfvars.example +0 -65
  83. package/templates/webapp/terraform/variables.tf +0 -129
@@ -1,101 +0,0 @@
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
- }
@@ -1,27 +0,0 @@
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
-
@@ -1,10 +0,0 @@
1
- output "trail_arn" {
2
- description = "ARN of the CloudTrail trail"
3
- value = aws_cloudtrail.trail.arn
4
- }
5
-
6
- output "trail_name" {
7
- description = "Name of the CloudTrail trail"
8
- value = aws_cloudtrail.trail.name
9
- }
10
-
@@ -1,15 +0,0 @@
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
-
@@ -1,118 +0,0 @@
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
- }
@@ -1,38 +0,0 @@
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
- }
@@ -1,24 +0,0 @@
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
- }
@@ -1,227 +0,0 @@
1
- data "aws_region" "current" {}
2
-
3
- data "http" "rds_ca" {
4
- url = "https://truststore.pki.rds.amazonaws.com/${data.aws_region.current.name}/${data.aws_region.current.name}-bundle.pem"
5
- }
6
-
7
- data "aws_vpc" "vpc" {
8
- id = var.vpc_id
9
- }
10
-
11
- data "aws_subnet" "subnet" {
12
- count = length(var.subnet_ids)
13
- id = var.subnet_ids[count.index]
14
- }
15
-
16
- # Check if existing cluster exists
17
- data "aws_rds_cluster" "existing" {
18
- count = var.existing_cluster_name != null ? 1 : 0
19
- cluster_identifier = var.existing_cluster_name
20
- }
21
-
22
- resource "random_pet" "name" {
23
- count = var.create_new_cluster && var.existing_cluster_name == null ? 1 : 0
24
- length = 2
25
- }
26
-
27
- resource "random_password" "master_password" {
28
- count = var.create_new_cluster && var.existing_cluster_name == null ? 1 : 0
29
- length = 16
30
- special = true
31
- override_special = "_!%^"
32
- }
33
-
34
-
35
- locals {
36
- cluster_name = var.existing_cluster_name != null ? var.existing_cluster_name : (var.create_new_cluster ? "${var.name}-${random_pet.name[0].id}" : null)
37
-
38
- # Use existing cluster details if available, otherwise use new cluster details
39
- cluster_endpoint = var.existing_cluster_name != null ? data.aws_rds_cluster.existing[0].endpoint : (var.create_new_cluster ? aws_rds_cluster.rds[0].endpoint : null)
40
- cluster_port = var.existing_cluster_name != null ? data.aws_rds_cluster.existing[0].port : (var.create_new_cluster ? aws_rds_cluster.rds[0].port : null)
41
- master_username = var.existing_cluster_name != null ? data.aws_rds_cluster.existing[0].master_username : (var.create_new_cluster ? aws_rds_cluster.rds[0].master_username : null)
42
- master_password = var.existing_cluster_name != null ? null : (var.create_new_cluster ? random_password.master_password[0].result : null)
43
- }
44
-
45
- # Security group for new RDS cluster
46
- resource "aws_security_group" "security_group" {
47
- count = var.create_new_cluster && var.existing_cluster_name == null ? 1 : 0
48
- name = "rds-__APP_NAME__-${random_pet.name[0].id}"
49
- description = "Security group for __APP_NAME_UPPER__ RDS ${random_pet.name[0].id}"
50
- vpc_id = data.aws_vpc.vpc.id
51
-
52
- ingress {
53
- description = "Allow Postgres from VPC"
54
- from_port = var.port
55
- to_port = var.port
56
- protocol = "tcp"
57
- cidr_blocks = [data.aws_vpc.vpc.cidr_block]
58
- }
59
-
60
- egress {
61
- from_port = 0
62
- to_port = 0
63
- protocol = "-1"
64
- cidr_blocks = ["0.0.0.0/0"]
65
- }
66
- }
67
-
68
- # Subnet group for new RDS cluster
69
- resource "aws_db_subnet_group" "subnet_group" {
70
- count = var.create_new_cluster && var.existing_cluster_name == null ? 1 : 0
71
- name = "rds-__APP_NAME__-${random_pet.name[0].id}"
72
- description = "Subnet group for __APP_NAME_UPPER__ RDS ${random_pet.name[0].id}"
73
- subnet_ids = var.subnet_ids
74
- }
75
-
76
- # New RDS cluster
77
- resource "aws_rds_cluster" "rds" {
78
- count = var.create_new_cluster && var.existing_cluster_name == null ? 1 : 0
79
- cluster_identifier = local.cluster_name
80
- engine = "aurora-postgresql"
81
- engine_mode = "provisioned"
82
- engine_version = var.engine_version
83
- vpc_security_group_ids = [aws_security_group.security_group[0].id]
84
- db_subnet_group_name = aws_db_subnet_group.subnet_group[0].name
85
- availability_zones = slice(data.aws_subnet.subnet[*].availability_zone, 0, min(3, length(data.aws_subnet.subnet)))
86
- database_name = "__DB_NAME__"
87
- port = var.port
88
- master_username = "__APP_NAME_SNAKE___admin"
89
- master_password = random_password.master_password[0].result
90
- storage_encrypted = true
91
- backup_retention_period = 5
92
- preferred_backup_window = "07:00-09:00"
93
-
94
- skip_final_snapshot = true
95
- enable_http_endpoint = true
96
-
97
- serverlessv2_scaling_configuration {
98
- max_capacity = 1.0
99
- min_capacity = 0.0
100
- seconds_until_auto_pause = 3600
101
- }
102
- }
103
-
104
- # RDS cluster instance for new cluster
105
- resource "aws_rds_cluster_instance" "instance" {
106
- count = var.create_new_cluster && var.existing_cluster_name == null ? 1 : 0
107
- identifier = "${local.cluster_name}-instance-${count.index}"
108
- cluster_identifier = aws_rds_cluster.rds[0].id
109
- instance_class = var.instance_class
110
- engine = aws_rds_cluster.rds[0].engine
111
- engine_version = aws_rds_cluster.rds[0].engine_version
112
- publicly_accessible = false
113
- }
114
-
115
- # Store master password in AWS Secrets Manager for new cluster
116
- resource "aws_secretsmanager_secret" "master_password" {
117
- count = var.create_new_cluster && var.existing_cluster_name == null ? 1 : 0
118
- name_prefix = "rds-__APP_NAME__-master-password-${random_pet.name[0].id}-"
119
- }
120
-
121
- resource "aws_secretsmanager_secret_version" "master_password" {
122
- count = var.create_new_cluster && var.existing_cluster_name == null ? 1 : 0
123
- secret_id = aws_secretsmanager_secret.master_password[0].id
124
- secret_string = random_password.master_password[0].result
125
- }
126
-
127
- ################################################################################
128
- # EDW Readonly User Resources
129
- ################################################################################
130
-
131
- # Generate secure password for readonly user
132
- resource "random_password" "readonly_user_password" {
133
- length = 32
134
- special = true
135
- # Use PostgreSQL-safe special characters
136
- override_special = "!#$%&*()-_=+[]{}<>:?"
137
- }
138
-
139
- # Store readonly user credentials in Secrets Manager
140
- resource "aws_secretsmanager_secret" "readonly_user_credentials" {
141
- name_prefix = "rds-__APP_NAME__-readonly-${var.name}-${var.environment}-"
142
- description = "Readonly database credentials for EDW access to __APP_NAME_UPPER__ database"
143
-
144
- tags = {
145
- Name = "__APP_NAME__-readonly-credentials"
146
- Environment = var.environment
147
- Purpose = "EDW"
148
- }
149
- }
150
-
151
- resource "aws_secretsmanager_secret_version" "readonly_user_credentials" {
152
- secret_id = aws_secretsmanager_secret.readonly_user_credentials.id
153
- secret_string = jsonencode({
154
- username = "__APP_NAME_SNAKE___readonly"
155
- password = random_password.readonly_user_password.result
156
- host = local.cluster_endpoint
157
- port = local.cluster_port
158
- database = "__DB_NAME__"
159
- engine = "postgres"
160
- })
161
- }
162
-
163
- # Cross-account IAM role for EDW to assume
164
- resource "aws_iam_role" "edw_secret_reader_role" {
165
- count = length(var.edw_allowed_principals) > 0 ? 1 : 0
166
- name = "__APP_NAME_UPPER__-EDW-SecretReader-${var.name}-${var.environment}"
167
-
168
- assume_role_policy = jsonencode({
169
- Version = "2012-10-17"
170
- Statement = [
171
- {
172
- Effect = "Allow"
173
- Principal = {
174
- AWS = var.edw_allowed_principals
175
- }
176
- Action = "sts:AssumeRole"
177
- }
178
- ]
179
- })
180
-
181
- tags = {
182
- Name = "__APP_NAME__-edw-secret-reader"
183
- Environment = var.environment
184
- Purpose = "EDW"
185
- }
186
- }
187
-
188
- # IAM policy to allow reading the readonly credentials secret
189
- resource "aws_iam_policy" "edw_secret_reader_policy" {
190
- count = length(var.edw_allowed_principals) > 0 ? 1 : 0
191
- name = "__APP_NAME_UPPER__-EDW-SecretReader-Policy-${var.name}-${var.environment}"
192
- description = "Allows EDW to read __APP_NAME_UPPER__ readonly database credentials from Secrets Manager"
193
-
194
- policy = jsonencode({
195
- Version = "2012-10-17"
196
- Statement = [
197
- {
198
- Effect = "Allow"
199
- Action = [
200
- "secretsmanager:GetSecretValue",
201
- "secretsmanager:DescribeSecret"
202
- ]
203
- Resource = aws_secretsmanager_secret.readonly_user_credentials.arn
204
- }
205
- ]
206
- })
207
- }
208
-
209
- resource "aws_iam_role_policy_attachment" "edw_secret_reader_attach" {
210
- count = length(var.edw_allowed_principals) > 0 ? 1 : 0
211
- role = aws_iam_role.edw_secret_reader_role[0].name
212
- policy_arn = aws_iam_policy.edw_secret_reader_policy[0].arn
213
- }
214
-
215
- # Add ingress rule to security group for EDW VPC CIDR blocks
216
- resource "aws_security_group_rule" "edw_ingress" {
217
- count = var.create_new_cluster && var.existing_cluster_name == null && length(var.edw_vpc_cidr_blocks) > 0 ? 1 : 0
218
- type = "ingress"
219
- description = "Allow Postgres from EDW VPC via VPC peering"
220
- from_port = var.port
221
- to_port = var.port
222
- protocol = "tcp"
223
- cidr_blocks = var.edw_vpc_cidr_blocks
224
- security_group_id = aws_security_group.security_group[0].id
225
- }
226
-
227
-
@@ -1,73 +0,0 @@
1
- output "host" {
2
- description = "RDS cluster endpoint"
3
- value = local.cluster_endpoint
4
- }
5
-
6
- output "port" {
7
- description = "RDS cluster port"
8
- value = local.cluster_port
9
- }
10
-
11
- output "database_name" {
12
- description = "Database name"
13
- value = "__DB_NAME__"
14
- }
15
-
16
- output "username" {
17
- description = "Database username (master user)"
18
- value = local.master_username
19
- }
20
-
21
- output "password" {
22
- description = "Database password (master user)"
23
- value = local.master_password
24
- sensitive = true
25
- }
26
-
27
- output "ssl_cert" {
28
- description = "RDS CA certificate"
29
- value = data.http.rds_ca.response_body
30
- sensitive = true
31
- }
32
-
33
- output "connection_url" {
34
- description = "PostgreSQL connection URL"
35
- value = "postgresql://${local.master_username}:${local.master_password}@${local.cluster_endpoint}:${local.cluster_port}/__DB_NAME__"
36
- sensitive = true
37
- }
38
-
39
- output "cluster_name" {
40
- description = "RDS cluster name"
41
- value = local.cluster_name
42
- }
43
-
44
- output "master_username" {
45
- description = "RDS master username (for new clusters only)"
46
- value = local.master_username
47
- }
48
-
49
- output "master_password" {
50
- description = "RDS master password (for new clusters only)"
51
- value = local.master_password
52
- sensitive = true
53
- }
54
-
55
- output "readonly_username" {
56
- description = "Readonly database username for EDW access"
57
- value = "__APP_NAME_SNAKE___readonly"
58
- }
59
-
60
- output "readonly_user_secret_arn" {
61
- description = "ARN of the Secrets Manager secret containing readonly user credentials"
62
- value = aws_secretsmanager_secret.readonly_user_credentials.arn
63
- }
64
-
65
- output "readonly_user_secret_name" {
66
- description = "Name of the Secrets Manager secret containing readonly user credentials"
67
- value = aws_secretsmanager_secret.readonly_user_credentials.name
68
- }
69
-
70
- output "readonly_user_secret_reader_role_arn" {
71
- description = "ARN of the IAM role that EDW can assume to read the readonly credentials secret"
72
- value = length(var.edw_allowed_principals) > 0 ? aws_iam_role.edw_secret_reader_role[0].arn : null
73
- }