From 14a108d9078c52be0e23d71dce4cde2fe79ed4bd Mon Sep 17 00:00:00 2001
From: Joaquin Lopez <joaquin.lopez@dominodatalab.com>
Date: Mon, 18 Dec 2023 15:20:01 -0800
Subject: [PATCH 1/5] Applyable RDS instance

---
 examples/deploy/terraform/infra/variables.tf  |  8 ++++
 modules/infra/outputs.tf                      |  5 ++
 modules/infra/submodules/storage/outputs.tf   | 12 +++++
 modules/infra/submodules/storage/rds.tf       | 46 +++++++++++++++++++
 modules/infra/submodules/storage/variables.tf | 11 +++++
 modules/infra/variables.tf                    | 11 +++++
 6 files changed, 93 insertions(+)
 create mode 100644 modules/infra/submodules/storage/rds.tf

diff --git a/examples/deploy/terraform/infra/variables.tf b/examples/deploy/terraform/infra/variables.tf
index 83a8d25d..367d5602 100644
--- a/examples/deploy/terraform/infra/variables.tf
+++ b/examples/deploy/terraform/infra/variables.tf
@@ -235,6 +235,14 @@ variable "storage" {
     ecr = optional(object({
       force_destroy_on_deletion = optional(bool, true)
     }), {})
+    rds = optional(object({
+      enabled = optional(bool, false)
+      engine_version = optional(string, "15.4")
+      instance_class = optional(string, "db.m5.large")
+      multi_az = optional(bool, true)
+      allocated_storage = optional(number, 100)
+      deletion_protection = optional(bool, true)
+    }), {}),
   })
 
   default = {}
diff --git a/modules/infra/outputs.tf b/modules/infra/outputs.tf
index dd7f610f..c3f2ec6b 100644
--- a/modules/infra/outputs.tf
+++ b/modules/infra/outputs.tf
@@ -1,3 +1,8 @@
+output "rds_enabled" {
+    description = "fuck"
+    value = var.storage.rds.enabled
+}
+
 output "hostname" {
   description = "Domino instance URL."
   value       = try("${var.deploy_id}.${var.route53_hosted_zone_name}", null)
diff --git a/modules/infra/submodules/storage/outputs.tf b/modules/infra/submodules/storage/outputs.tf
index 3ebd597c..3e9b47b7 100644
--- a/modules/infra/submodules/storage/outputs.tf
+++ b/modules/infra/submodules/storage/outputs.tf
@@ -13,6 +13,12 @@ output "info" {
       container_registry = ECR base registry URL. Grab the base AWS account ECR URL and add the deploy_id. Domino will append /environment and /model.
       iam_policy_arn     = ECR IAM Policy ARN.
     }
+    rds = {
+      address = "Hostname of RDS Postgres instance"
+      port = "Port of RDS postgres instance"
+      username = "Master username for RDS postgres instance
+      master_user_secret = "Secret information for RDS postgres instance"
+    }
   EOF
   value = {
     efs = {
@@ -31,5 +37,11 @@ output "info" {
       container_registry = join("/", concat(slice(split("/", aws_ecr_repository.this["environment"].repository_url), 0, 1), [var.deploy_id]))
       iam_policy_arn     = aws_iam_policy.ecr.arn
     }
+    rds = {
+      address = var.storage.rds.enabled ? aws_db_instance.postgresql[0].address: null
+      port = var.storage.rds.enabled ? aws_db_instance.postgresql[0].port : null
+      username = var.storage.rds.enabled ? aws_db_instance.postgresql[0].username : null
+      master_user_secret = var.storage.rds.enabled ? aws_db_instance.postgresql[0].master_user_secret : null
+    }
   }
 }
diff --git a/modules/infra/submodules/storage/rds.tf b/modules/infra/submodules/storage/rds.tf
new file mode 100644
index 00000000..f93266e7
--- /dev/null
+++ b/modules/infra/submodules/storage/rds.tf
@@ -0,0 +1,46 @@
+resource "aws_security_group" "postgresql" {
+    count = var.storage.rds.enabled ? 1 : 0
+
+    name = "${var.deploy_id}-rds-postgresql"
+    description = "RDS Security Group"
+    vpc_id = var.network_info.vpc_id
+
+    lifecycle {
+        create_before_destroy = true
+    }
+}
+
+
+resource "aws_db_subnet_group" "postgresql" {
+    count = var.storage.rds.enabled ? 1 : 0
+
+    name = "postgresql"
+    subnet_ids = local.private_subnet_ids
+}
+
+resource "aws_db_instance" "postgresql" {
+    count = var.storage.rds.enabled ? 1 : 0
+
+    copy_tags_to_snapshot = true
+
+    engine = "postgres"
+    engine_version = var.storage.rds.engine_version
+
+    db_subnet_group_name = aws_db_subnet_group.postgresql[0].name
+    vpc_security_group_ids = [aws_security_group.postgresql[0].id]
+    instance_class = var.storage.rds.instance_class
+    multi_az = var.storage.rds.multi_az
+    allocated_storage = var.storage.rds.allocated_storage /* validate > 100? */
+
+    manage_master_user_password = true
+    username = "postgres"
+
+    publicly_accessible = false
+    
+    auto_minor_version_upgrade = true
+
+    deletion_protection = var.storage.rds.deletion_protection
+    skip_final_snapshot = ! var.storage.rds.deletion_protection
+    delete_automated_backups = ! var.storage.rds.deletion_protection
+    final_snapshot_identifier = var.deploy_id
+}
diff --git a/modules/infra/submodules/storage/variables.tf b/modules/infra/submodules/storage/variables.tf
index 9a535c86..28db3e4b 100644
--- a/modules/infra/submodules/storage/variables.tf
+++ b/modules/infra/submodules/storage/variables.tf
@@ -42,6 +42,9 @@ variable "storage" {
       ecr = {
         force_destroy_on_deletion = Toogle to allow recursive deletion of all objects in the ECR repositories. if 'false' terraform will NOT be able to delete non-empty repositories.
       }
+      rds = {
+        enabled = "Toggle to enable provisioning RDS server for hosted postgres"
+      }
       enable_remote_backup = Enable tagging required for cross-account backups
       costs_enabled = Determines whether to provision domino cost related infrastructures, ie, long term storage
     }
@@ -66,6 +69,14 @@ variable "storage" {
     ecr = optional(object({
       force_destroy_on_deletion = optional(bool)
     }))
+    rds = optional(object({
+      enabled = optional(bool, false)
+      engine_version = optional(string, "15.4")
+      instance_class = optional(string, "db.m5.large")
+      multi_az = optional(bool, true)
+      allocated_storage = optional(number, 100)
+      deletion_protection = optional(bool, true)
+    }), {}),
     enable_remote_backup = optional(bool)
     costs_enabled        = optional(bool)
   })
diff --git a/modules/infra/variables.tf b/modules/infra/variables.tf
index e7d1e44c..a6455695 100644
--- a/modules/infra/variables.tf
+++ b/modules/infra/variables.tf
@@ -349,6 +349,9 @@ variable "storage" {
       ecr = {
         force_destroy_on_deletion = Toogle to allow recursive deletion of all objects in the ECR repositories. if 'false' terraform will NOT be able to delete non-empty repositories.
       }
+      rds = {
+        enabled = "Toggle to enable provisioning RDS server for hosted postgres"
+      }
       enable_remote_backup = Enable tagging required for cross-account backups
       costs_enabled = Determines whether to provision domino cost related infrastructures, ie, long term storage
     }
@@ -373,6 +376,14 @@ variable "storage" {
     ecr = optional(object({
       force_destroy_on_deletion = optional(bool, true)
     }), {}),
+    rds = optional(object({
+      enabled = optional(bool, false)
+      engine_version = optional(string, "15.4")
+      instance_class = optional(string, "db.m5.large")
+      multi_az = optional(bool, true)
+      allocated_storage = optional(number, 100)
+      deletion_protection = optional(bool, true)
+    }), {}),
     enable_remote_backup = optional(bool, false)
     costs_enabled        = optional(bool, true)
   })

From 7c7b94d120e62dfeb8f8ab2536c50c1f0e213f03 Mon Sep 17 00:00:00 2001
From: Joaquin Lopez <joaquin.lopez@dominodatalab.com>
Date: Mon, 18 Dec 2023 15:37:47 -0800
Subject: [PATCH 2/5] Set deletion protection to false for testing

---
 examples/deploy/terraform/infra.tfvars | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/examples/deploy/terraform/infra.tfvars b/examples/deploy/terraform/infra.tfvars
index dfb3fca8..31732a63 100644
--- a/examples/deploy/terraform/infra.tfvars
+++ b/examples/deploy/terraform/infra.tfvars
@@ -50,6 +50,10 @@ storage = {
   ecr = {
     force_destroy_on_deletion = true
   }
+  rds = {
+    enabled = false
+    deletion_protection = false
+  }
   efs = {
     access_point_path = "/domino"
     backup_vault = {

From 15925a04cf5ea4737d64a5f4e040112577df83aa Mon Sep 17 00:00:00 2001
From: Joaquin Lopez <joaquin.lopez@dominodatalab.com>
Date: Mon, 18 Dec 2023 17:36:50 -0800
Subject: [PATCH 3/5] Wire up security group

---
 examples/deploy/terraform/cluster/main.tf   |  1 +
 modules/eks/node-group.tf                   | 11 +++++++++++
 modules/eks/variables.tf                    |  5 +++++
 modules/infra/outputs.tf                    |  5 +++++
 modules/infra/submodules/storage/outputs.tf |  1 +
 5 files changed, 23 insertions(+)

diff --git a/examples/deploy/terraform/cluster/main.tf b/examples/deploy/terraform/cluster/main.tf
index 2f0383e0..07d10696 100644
--- a/examples/deploy/terraform/cluster/main.tf
+++ b/examples/deploy/terraform/cluster/main.tf
@@ -19,6 +19,7 @@ module "eks" {
   ssh_key             = local.infra.ssh_key
   node_iam_policies   = local.infra.node_iam_policies
   efs_security_group  = local.infra.efs_security_group
+  rds_security_group  = local.infra.rds_security_group
   eks                 = var.eks
   network_info        = local.infra.network
   kms_info            = local.kms
diff --git a/modules/eks/node-group.tf b/modules/eks/node-group.tf
index cd0f015a..7e252ba9 100644
--- a/modules/eks/node-group.tf
+++ b/modules/eks/node-group.tf
@@ -60,3 +60,14 @@ resource "aws_security_group_rule" "efs" {
   description              = "EFS access"
   source_security_group_id = aws_security_group.eks_nodes.id
 }
+
+resource "aws_security_group_rule" "rds-postgres" {
+  count                    = var.rds_security_group != null ? 1 : 0
+  security_group_id        = var.rds_security_group
+  protocol                 = "tcp"
+  from_port                = 5432
+  to_port                  = 5432
+  type                     = "ingress"
+  description              = "RDS postgres access"
+  source_security_group_id = aws_security_group.eks_nodes.id
+}
diff --git a/modules/eks/variables.tf b/modules/eks/variables.tf
index 89bbab0e..6c5e212a 100644
--- a/modules/eks/variables.tf
+++ b/modules/eks/variables.tf
@@ -89,6 +89,11 @@ variable "efs_security_group" {
   type        = string
 }
 
+variable "rds_security_group" {
+  description = "Security Group ID for RDS postgres"
+  type        = string
+}
+
 variable "bastion_info" {
   description = <<EOF
     user                = Bastion username.
diff --git a/modules/infra/outputs.tf b/modules/infra/outputs.tf
index c3f2ec6b..6cbda344 100644
--- a/modules/infra/outputs.tf
+++ b/modules/infra/outputs.tf
@@ -71,6 +71,11 @@ output "efs_security_group" {
   value       = module.storage.info.efs.security_group_id
 }
 
+output "rds_security_group" {
+  description = "Security Group ID for RDS postgres"
+  value       = module.storage.info.rds.security_group_id
+}
+
 output "node_iam_policies" {
   description = "Policies attached to EKS nodes role"
   value       = local.node_iam_policies
diff --git a/modules/infra/submodules/storage/outputs.tf b/modules/infra/submodules/storage/outputs.tf
index 3e9b47b7..e1d4882b 100644
--- a/modules/infra/submodules/storage/outputs.tf
+++ b/modules/infra/submodules/storage/outputs.tf
@@ -42,6 +42,7 @@ output "info" {
       port = var.storage.rds.enabled ? aws_db_instance.postgresql[0].port : null
       username = var.storage.rds.enabled ? aws_db_instance.postgresql[0].username : null
       master_user_secret = var.storage.rds.enabled ? aws_db_instance.postgresql[0].master_user_secret : null
+      security_group_id = var.storage.rds.enabled ? aws_security_group.postgres.id : null
     }
   }
 }

From eb9d7f99d8a1f158b931287ef0c00ae744e45f84 Mon Sep 17 00:00:00 2001
From: Joaquin Lopez <joaquin.lopez@dominodatalab.com>
Date: Mon, 18 Dec 2023 17:40:43 -0800
Subject: [PATCH 4/5] s/postgres/postgresql/

---
 modules/eks/node-group.tf                   | 4 ++--
 modules/eks/variables.tf                    | 2 +-
 modules/infra/outputs.tf                    | 2 +-
 modules/infra/submodules/storage/outputs.tf | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/modules/eks/node-group.tf b/modules/eks/node-group.tf
index 7e252ba9..bed5852d 100644
--- a/modules/eks/node-group.tf
+++ b/modules/eks/node-group.tf
@@ -61,13 +61,13 @@ resource "aws_security_group_rule" "efs" {
   source_security_group_id = aws_security_group.eks_nodes.id
 }
 
-resource "aws_security_group_rule" "rds-postgres" {
+resource "aws_security_group_rule" "rds-postgresql" {
   count                    = var.rds_security_group != null ? 1 : 0
   security_group_id        = var.rds_security_group
   protocol                 = "tcp"
   from_port                = 5432
   to_port                  = 5432
   type                     = "ingress"
-  description              = "RDS postgres access"
+  description              = "RDS postgresql access"
   source_security_group_id = aws_security_group.eks_nodes.id
 }
diff --git a/modules/eks/variables.tf b/modules/eks/variables.tf
index 6c5e212a..45c313ca 100644
--- a/modules/eks/variables.tf
+++ b/modules/eks/variables.tf
@@ -90,7 +90,7 @@ variable "efs_security_group" {
 }
 
 variable "rds_security_group" {
-  description = "Security Group ID for RDS postgres"
+  description = "Security Group ID for RDS postgresql"
   type        = string
 }
 
diff --git a/modules/infra/outputs.tf b/modules/infra/outputs.tf
index 6cbda344..dc9bc0a8 100644
--- a/modules/infra/outputs.tf
+++ b/modules/infra/outputs.tf
@@ -72,7 +72,7 @@ output "efs_security_group" {
 }
 
 output "rds_security_group" {
-  description = "Security Group ID for RDS postgres"
+  description = "Security Group ID for RDS postgresql"
   value       = module.storage.info.rds.security_group_id
 }
 
diff --git a/modules/infra/submodules/storage/outputs.tf b/modules/infra/submodules/storage/outputs.tf
index e1d4882b..b0ab7ae2 100644
--- a/modules/infra/submodules/storage/outputs.tf
+++ b/modules/infra/submodules/storage/outputs.tf
@@ -42,7 +42,7 @@ output "info" {
       port = var.storage.rds.enabled ? aws_db_instance.postgresql[0].port : null
       username = var.storage.rds.enabled ? aws_db_instance.postgresql[0].username : null
       master_user_secret = var.storage.rds.enabled ? aws_db_instance.postgresql[0].master_user_secret : null
-      security_group_id = var.storage.rds.enabled ? aws_security_group.postgres.id : null
+      security_group_id = var.storage.rds.enabled ? aws_security_group.postgresql.id : null
     }
   }
 }

From 9dfbe68e5fe298bd4fcd8b3ee5ad6e72991a8c4b Mon Sep 17 00:00:00 2001
From: Joaquin Lopez <joaquin.lopez@dominodatalab.com>
Date: Mon, 18 Dec 2023 17:41:51 -0800
Subject: [PATCH 5/5] index

---
 modules/infra/submodules/storage/outputs.tf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/infra/submodules/storage/outputs.tf b/modules/infra/submodules/storage/outputs.tf
index b0ab7ae2..9844c98b 100644
--- a/modules/infra/submodules/storage/outputs.tf
+++ b/modules/infra/submodules/storage/outputs.tf
@@ -42,7 +42,7 @@ output "info" {
       port = var.storage.rds.enabled ? aws_db_instance.postgresql[0].port : null
       username = var.storage.rds.enabled ? aws_db_instance.postgresql[0].username : null
       master_user_secret = var.storage.rds.enabled ? aws_db_instance.postgresql[0].master_user_secret : null
-      security_group_id = var.storage.rds.enabled ? aws_security_group.postgresql.id : null
+      security_group_id = var.storage.rds.enabled ? aws_security_group.postgresql[0].id : null
     }
   }
 }