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 } } }