From 32068e7dcd729b2ba70d0c74035b8b85aa4e629a Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Thu, 20 Nov 2025 18:26:08 -0500 Subject: [PATCH 01/10] RDSC-4001 Example for RDS Aurora Postgres DB failover --- modules/aws-privatelink/inputs.tf | 6 +- modules/aws-privatelink/load-balancer.tf | 4 +- modules/aws-privatelink/output.tf | 8 +++ modules/aws-rds-chinook/data.tf | 4 ++ modules/aws-rds-chinook/input.tf | 44 +++++++++++++ modules/aws-rds-chinook/locals.tf | 4 ++ modules/aws-rds-chinook/main.tf | 22 +++++++ modules/aws-rds-chinook/output.tf | 19 ++++++ modules/aws-rds-chinook/security.tf | 27 ++++++++ modules/aws-rds-chinook/vpc.tf | 18 ++++++ modules/aws-rds-lambda/.gitignore | 1 + modules/aws-rds-lambda/iam.tf | 59 +++++++++++++++++ modules/aws-rds-lambda/inputs.tf | 20 ++++++ modules/aws-rds-lambda/lambda.py | 80 ++++++++++++++++++++++++ modules/aws-rds-lambda/lambda.tf | 29 +++++++++ modules/aws-rds-lambda/sns.tf | 55 ++++++++++++++++ 16 files changed, 396 insertions(+), 4 deletions(-) create mode 100644 modules/aws-rds-chinook/data.tf create mode 100644 modules/aws-rds-chinook/input.tf create mode 100644 modules/aws-rds-chinook/locals.tf create mode 100644 modules/aws-rds-chinook/main.tf create mode 100644 modules/aws-rds-chinook/output.tf create mode 100644 modules/aws-rds-chinook/security.tf create mode 100644 modules/aws-rds-chinook/vpc.tf create mode 100644 modules/aws-rds-lambda/.gitignore create mode 100644 modules/aws-rds-lambda/iam.tf create mode 100644 modules/aws-rds-lambda/inputs.tf create mode 100644 modules/aws-rds-lambda/lambda.py create mode 100644 modules/aws-rds-lambda/lambda.tf create mode 100644 modules/aws-rds-lambda/sns.tf diff --git a/modules/aws-privatelink/inputs.tf b/modules/aws-privatelink/inputs.tf index 21b82b2..aa15213 100644 --- a/modules/aws-privatelink/inputs.tf +++ b/modules/aws-privatelink/inputs.tf @@ -8,9 +8,9 @@ variable "port" { description = "The port to listen on and forward to in the target group" } -variable "target" { - type = string - description = "The identifier of the load balancer target - this can be an ip or EC2 instance ID" +variable "targets" { + type = list(string) + description = "The identifier of the load balancer targets - this can be an ip or EC2 instance ID" } variable "target_type" { diff --git a/modules/aws-privatelink/load-balancer.tf b/modules/aws-privatelink/load-balancer.tf index c54c108..8fc702d 100644 --- a/modules/aws-privatelink/load-balancer.tf +++ b/modules/aws-privatelink/load-balancer.tf @@ -51,7 +51,9 @@ resource "aws_lb_target_group" "producer_tg" { # Attach the EC2 instance to the target group resource "aws_lb_target_group_attachment" "producer_tga" { + for_each = toset(var.targets) + target_group_arn = aws_lb_target_group.producer_tg.arn - target_id = var.target + target_id = each.value port = var.port } diff --git a/modules/aws-privatelink/output.tf b/modules/aws-privatelink/output.tf index 8c7aa79..6ffea73 100644 --- a/modules/aws-privatelink/output.tf +++ b/modules/aws-privatelink/output.tf @@ -12,3 +12,11 @@ output "vpc_endpoint_service_id" { value = aws_vpc_endpoint_service.producer_service.id description = "The ID of the VPC endpoint service - source Private Link service ID" } + +output "lb_hostname" { + value = aws_lb.producer_nlb.dns_name +} + +output "tg_arn" { + value = aws_lb_target_group.producer_tg.arn +} diff --git a/modules/aws-rds-chinook/data.tf b/modules/aws-rds-chinook/data.tf new file mode 100644 index 0000000..122e28d --- /dev/null +++ b/modules/aws-rds-chinook/data.tf @@ -0,0 +1,4 @@ +# Needed for subnet creation +data "aws_availability_zones" "available" { + state = "available" +} diff --git a/modules/aws-rds-chinook/input.tf b/modules/aws-rds-chinook/input.tf new file mode 100644 index 0000000..45f3997 --- /dev/null +++ b/modules/aws-rds-chinook/input.tf @@ -0,0 +1,44 @@ +variable "vpc_cidr" { + description = "The CIDR block for the VPC" + type = string + default = "10.0.0.0/20" +} + +variable "azs" { + description = "A list of availability zones to deploy the EKS cluster into" + type = list(string) + default = ["use1-az2", "use1-az4", "use1-az6"] +} + +variable "public_subnet_cidr" { + description = "The CIDR block for the public subnet" + type = list(string) + default = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] +} + +variable "private_subnet_cidr" { + description = "The CIDR block for the public subnet" + type = list(string) + default = ["10.0.7.0/24", "10.0.8.0/24", "10.0.9.0/24"] +} + +variable "database_subnet_cidr" { + description = "The CIDR block for the public subnet" + type = list(string) + default = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"] +} + +variable "identifier" { + description = "The identifier for the resources/test" + type = string +} + +variable "db_password" { + description = "The password for connecting to the Producer Source Database" + type = string +} + +variable "db_port" { + description = "The port for connecting to the Producer Source Database" + type = number +} diff --git a/modules/aws-rds-chinook/locals.tf b/modules/aws-rds-chinook/locals.tf new file mode 100644 index 0000000..1e701e2 --- /dev/null +++ b/modules/aws-rds-chinook/locals.tf @@ -0,0 +1,4 @@ +locals { + az_map = zipmap(data.aws_availability_zones.available.zone_ids, data.aws_availability_zones.available.names) + azs = [for az_id in var.azs : local.az_map[az_id]] +} diff --git a/modules/aws-rds-chinook/main.tf b/modules/aws-rds-chinook/main.tf new file mode 100644 index 0000000..e5f3c69 --- /dev/null +++ b/modules/aws-rds-chinook/main.tf @@ -0,0 +1,22 @@ +resource "aws_rds_cluster" "postgresql" { + cluster_identifier = "aurora-${var.identifier}" + engine = "aurora-postgresql" + database_name = "chinook" + master_username = "postgres" + master_password = var.db_password + backup_retention_period = 5 + preferred_backup_window = "07:00-09:00" + skip_final_snapshot = true + db_subnet_group_name = module.vpc.database_subnet_group_name + vpc_security_group_ids = [aws_security_group.producer_sg.id] +} + +resource "aws_rds_cluster_instance" "cluster_instances" { + count = 2 + identifier = "${var.identifier}-${count.index}" + cluster_identifier = aws_rds_cluster.postgresql.id + instance_class = "db.t4g.medium" + engine = aws_rds_cluster.postgresql.engine + engine_version = aws_rds_cluster.postgresql.engine_version + db_subnet_group_name = module.vpc.database_subnet_group_name +} diff --git a/modules/aws-rds-chinook/output.tf b/modules/aws-rds-chinook/output.tf new file mode 100644 index 0000000..17ccc1b --- /dev/null +++ b/modules/aws-rds-chinook/output.tf @@ -0,0 +1,19 @@ +output "vpc_id" { + value = module.vpc.vpc_id +} + +output "vpc_public_subnets" { + value = module.vpc.public_subnets +} + +output "rds_arn" { + value = aws_rds_cluster.postgresql.arn +} + +output "rds_endpoint" { + value = aws_rds_cluster.postgresql.endpoint +} + +output "security_group_id" { + value = aws_security_group.producer_sg.id +} diff --git a/modules/aws-rds-chinook/security.tf b/modules/aws-rds-chinook/security.tf new file mode 100644 index 0000000..cf773ac --- /dev/null +++ b/modules/aws-rds-chinook/security.tf @@ -0,0 +1,27 @@ +# Creating the security group for the producer instance +resource "aws_security_group" "producer_sg" { + vpc_id = module.vpc.vpc_id + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + # To be able to connect to postgres from the LB + ingress { + from_port = var.db_port + to_port = var.db_port + protocol = "tcp" + self = true + } + # To be able to connect to postgres from the demo machine + ingress { + from_port = var.db_port + to_port = var.db_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + tags = { + Name = "producer-sg-${var.identifier}" + } +} diff --git a/modules/aws-rds-chinook/vpc.tf b/modules/aws-rds-chinook/vpc.tf new file mode 100644 index 0000000..48cf49e --- /dev/null +++ b/modules/aws-rds-chinook/vpc.tf @@ -0,0 +1,18 @@ +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "5.8.1" + + name = "producer-vpc-${var.identifier}" + + cidr = var.vpc_cidr + map_public_ip_on_launch = true + + azs = local.azs + public_subnets = var.public_subnet_cidr + private_subnets = var.private_subnet_cidr + database_subnets = var.database_subnet_cidr + + tags = { + Name = "producer-vpc-${var.identifier}" + } +} diff --git a/modules/aws-rds-lambda/.gitignore b/modules/aws-rds-lambda/.gitignore new file mode 100644 index 0000000..5405084 --- /dev/null +++ b/modules/aws-rds-lambda/.gitignore @@ -0,0 +1 @@ +function.zip diff --git a/modules/aws-rds-lambda/iam.tf b/modules/aws-rds-lambda/iam.tf new file mode 100644 index 0000000..04ad814 --- /dev/null +++ b/modules/aws-rds-lambda/iam.tf @@ -0,0 +1,59 @@ +# Lambda Execution Role +resource "aws_iam_role" "lambda_execution_role" { + name = "${var.identifier}-lambda-execution-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "lambda.amazonaws.com" + } + } + ] + }) +} + +resource "aws_iam_role_policy" "ec2_elb_lambda_execution_role_policy" { + name = "${var.identifier}-ec2-elb-lambda-execution-role-policy" + role = aws_iam_role.lambda_execution_role.id + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "ec2:CreateNetworkInterface", + "ec2:DeleteNetworkInterface", + "ec2:DescribeNetworkInterfaces", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:RegisterTargets" + ] + Resource = "*" + } + ] + }) +} + +resource "aws_iam_role_policy" "log_group_lambda_execution_role_policy" { + name = "${var.identifier}-log-group-lambda-execution-role-policy" + role = aws_iam_role.lambda_execution_role.id + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ] + Resource = "*" + } + ] + }) +} + diff --git a/modules/aws-rds-lambda/inputs.tf b/modules/aws-rds-lambda/inputs.tf new file mode 100644 index 0000000..b192b5e --- /dev/null +++ b/modules/aws-rds-lambda/inputs.tf @@ -0,0 +1,20 @@ +variable "identifier" { + description = "The identifier for the resources/test" + type = string +} + +variable "db_endpoint" { + type = string +} + +variable "db_port" { + type = number +} + +variable "elb_tg_arn" { + type = string +} + +variable "rds_arn" { + type = string +} diff --git a/modules/aws-rds-lambda/lambda.py b/modules/aws-rds-lambda/lambda.py new file mode 100644 index 0000000..7724398 --- /dev/null +++ b/modules/aws-rds-lambda/lambda.py @@ -0,0 +1,80 @@ +import os +import json +import socket +import sys +import boto3 + +# Get Environment varilables +vCluster = os.environ.get('Cluster_EndPoint') +vELB_arn = os.environ.get('NLB_TG_ARN') +vNewPort = os.environ.get('RDS_Port') +client = boto3.client('elbv2') + +def lambda_handler(event, context): + + # DeRegister old IP from NLB + def deregister_oldip(vOldIp, vOldPort, vOldAZ): + response = client.deregister_targets( + TargetGroupArn=vELB_arn, + Targets=[ + { + 'Id': vOldIp, + 'Port': vOldPort, + 'AvailabilityZone': vOldAZ + }, + ] + ) + +# Register new IP to NLB + def register_newip(vNewIP, vNewPort): + response = client.register_targets( + TargetGroupArn=vELB_arn, + Targets=[ + { + 'Id': vNewIP, + 'Port': int(vNewPort) + }, + ] + ) + +# Get Master Node IP address + vNewIP = socket.gethostbyname_ex(vCluster) + IPs = vNewIP[2] + print('IP list from DNS: ', IPs) + +# Get Registered IP detail from NLB + dictNLB = client.describe_target_health( + TargetGroupArn=vELB_arn + ) + + ip_list = [] + for i in dictNLB['TargetHealthDescriptions']: + ip = i.get('Target').get('Id') + ip_list.append(ip) + + if not ip_list: + for nIP in IPs: + print('Register New IP ', nIP, 'Port: ', vNewPort) + register_newip(nIP, vNewPort) + + DeRegisterIP = set(ip_list) - set(IPs) + RegisterIP = set(IPs) - set(ip_list) + + if DeRegisterIP: + print('IP: ', str(DeRegisterIP), ' will be DeRegistered from NLB Target') + + if RegisterIP: + print('IP: ', str(RegisterIP), ' will be registered to NLB Target') + + for nIP in RegisterIP: + print('Registering New IP ', nIP, 'Port: ', vNewPort) + register_newip(nIP, vNewPort) + + for oIP in dictNLB['TargetHealthDescriptions']: + vOldIp = oIP.get('Target').get('Id') + vOldPort = oIP.get('Target').get('Port') + vOldAZ = oIP.get('Target').get('AvailabilityZone') + print('IP list from NLB Target Group: ', vOldIp) + if vOldIp in DeRegisterIP: + print('DeRegister IP: ', vOldIp, 'Port; ', vOldPort, 'AZ: ', vOldAZ) + deregister_oldip(vOldIp, vOldPort, vOldAZ) diff --git a/modules/aws-rds-lambda/lambda.tf b/modules/aws-rds-lambda/lambda.tf new file mode 100644 index 0000000..d49d631 --- /dev/null +++ b/modules/aws-rds-lambda/lambda.tf @@ -0,0 +1,29 @@ +resource "aws_lambda_function" "rdi_failover_lambda" { + filename = data.archive_file.rdi_failover_lambda.output_path + function_name = var.identifier + role = aws_iam_role.lambda_execution_role.arn + handler = "lambda.lambda_handler" + environment { + variables = { + Cluster_EndPoint = var.db_endpoint + RDS_Port = var.db_port + NLB_TG_ARN = var.elb_tg_arn + } + } + runtime = "python3.12" + timeout = 300 + memory_size = 128 + + depends_on = [aws_cloudwatch_log_group.rdi] +} + +resource "aws_cloudwatch_log_group" "rdi" { + name = "/aws/lambda/${var.identifier}" + retention_in_days = 14 +} + +data "archive_file" "rdi_failover_lambda" { + type = "zip" + source_file = "${path.module}/lambda.py" + output_path = "${path.module}/function.zip" +} diff --git a/modules/aws-rds-lambda/sns.tf b/modules/aws-rds-lambda/sns.tf new file mode 100644 index 0000000..f876e22 --- /dev/null +++ b/modules/aws-rds-lambda/sns.tf @@ -0,0 +1,55 @@ +# SNS Topic +resource "aws_sns_topic" "rdi_failover_topic" { + name = var.identifier + display_name = "RDI Failover Topic" +} + +resource "aws_sns_topic_policy" "rdi_failover_topic_policy" { + arn = aws_sns_topic.rdi_failover_topic.arn + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Principal = { + AWS = "*" + } + Action = [ + "SNS:GetTopicAttributes", + "SNS:SetTopicAttributes", + "SNS:AddPermission", + "SNS:RemovePermission", + "SNS:DeleteTopic", + "SNS:Subscribe", + "SNS:ListSubscriptionsByTopic", + "SNS:Publish", + "SNS:Receive" + ] + Resource = aws_sns_topic.rdi_failover_topic.arn + } + ] + }) +} + +resource "aws_sns_topic_subscription" "rdi_failover_subscription" { + topic_arn = aws_sns_topic.rdi_failover_topic.arn + protocol = "lambda" + endpoint = aws_lambda_function.rdi_failover_lambda.arn +} + +resource "aws_db_event_subscription" "rds_instance_failover_event" { + name = "${var.identifier}-rds-instance-events" + sns_topic = aws_sns_topic.rdi_failover_topic.arn + event_categories = ["creation", "failover", "failure"] + source_type = "db-cluster" + source_ids = [split(".", var.db_endpoint)[0]] + enabled = true +} + +resource "aws_lambda_permission" "with_sns" { + statement_id = "AllowExecutionFromSNS" + action = "lambda:InvokeFunction" + function_name = aws_lambda_function.rdi_failover_lambda.arn + principal = "sns.amazonaws.com" + source_arn = aws_sns_topic.rdi_failover_topic.arn +} From 2ac890bbf04947fba7dc6b4a73986272650d4bf4 Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Thu, 20 Nov 2025 18:28:36 -0500 Subject: [PATCH 02/10] Add example directory --- examples/aws-rds-privatelink/.gitignore | 8 ++ .../aws-rds-privatelink/.terraform.lock.hcl | 83 +++++++++++++++++++ examples/aws-rds-privatelink/README.md | 34 ++++++++ examples/aws-rds-privatelink/example.tfvars | 6 ++ examples/aws-rds-privatelink/inputs.tf | 36 ++++++++ examples/aws-rds-privatelink/main.tf | 75 +++++++++++++++++ examples/aws-rds-privatelink/outputs.tf | 35 ++++++++ examples/aws-rds-privatelink/psql.sh | 5 ++ examples/aws-rds-privatelink/psql_setup.tf | 15 ++++ examples/aws-rds-privatelink/rds.tf | 1 + 10 files changed, 298 insertions(+) create mode 100644 examples/aws-rds-privatelink/.gitignore create mode 100644 examples/aws-rds-privatelink/.terraform.lock.hcl create mode 100644 examples/aws-rds-privatelink/README.md create mode 100644 examples/aws-rds-privatelink/example.tfvars create mode 100644 examples/aws-rds-privatelink/inputs.tf create mode 100644 examples/aws-rds-privatelink/main.tf create mode 100644 examples/aws-rds-privatelink/outputs.tf create mode 100755 examples/aws-rds-privatelink/psql.sh create mode 100644 examples/aws-rds-privatelink/psql_setup.tf create mode 100644 examples/aws-rds-privatelink/rds.tf diff --git a/examples/aws-rds-privatelink/.gitignore b/examples/aws-rds-privatelink/.gitignore new file mode 100644 index 0000000..a8711e0 --- /dev/null +++ b/examples/aws-rds-privatelink/.gitignore @@ -0,0 +1,8 @@ +.terraform +.idea +producer +producer-west +userdata.tgz +scripts +mysql.log +*.tfstate.*.backup diff --git a/examples/aws-rds-privatelink/.terraform.lock.hcl b/examples/aws-rds-privatelink/.terraform.lock.hcl new file mode 100644 index 0000000..46343a3 --- /dev/null +++ b/examples/aws-rds-privatelink/.terraform.lock.hcl @@ -0,0 +1,83 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/archive" { + version = "2.7.1" + hashes = [ + "h1:A7EnRBVm4h9ryO9LwxYnKr4fy7ExPMwD5a1DsY7m1Y0=", + "zh:19881bb356a4a656a865f48aee70c0b8a03c35951b7799b6113883f67f196e8e", + "zh:2fcfbf6318dd514863268b09bbe19bfc958339c636bcbcc3664b45f2b8bf5cc6", + "zh:3323ab9a504ce0a115c28e64d0739369fe85151291a2ce480d51ccbb0c381ac5", + "zh:362674746fb3da3ab9bd4e70c75a3cdd9801a6cf258991102e2c46669cf68e19", + "zh:7140a46d748fdd12212161445c46bbbf30a3f4586c6ac97dd497f0c2565fe949", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:875e6ce78b10f73b1efc849bfcc7af3a28c83a52f878f503bb22776f71d79521", + "zh:b872c6ed24e38428d817ebfb214da69ea7eefc2c38e5a774db2ccd58e54d3a22", + "zh:cd6a44f731c1633ae5d37662af86e7b01ae4c96eb8b04144255824c3f350392d", + "zh:e0600f5e8da12710b0c52d6df0ba147a5486427c1a2cc78f31eea37a47ee1b07", + "zh:f21b2e2563bbb1e44e73557bcd6cdbc1ceb369d471049c40eb56cb84b6317a60", + "zh:f752829eba1cc04a479cf7ae7271526b402e206d5bcf1fcce9f535de5ff9e4e6", + ] +} + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.100.0" + constraints = ">= 4.66.0, ~> 5.0, >= 5.30.0" + hashes = [ + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.4" + hashes = [ + "h1:L5V05xwp/Gto1leRryuesxjMfgZwjb7oool4WS1UEFQ=", + "zh:59f6b52ab4ff35739647f9509ee6d93d7c032985d9f8c6237d1f8a59471bbbe2", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:795c897119ff082133150121d39ff26cb5f89a730a2c8c26f3a9c1abf81a9c43", + "zh:7b9c7b16f118fbc2b05a983817b8ce2f86df125857966ad356353baf4bff5c0a", + "zh:85e33ab43e0e1726e5f97a874b8e24820b6565ff8076523cc2922ba671492991", + "zh:9d32ac3619cfc93eb3c4f423492a8e0f79db05fec58e449dee9b2d5873d5f69f", + "zh:9e15c3c9dd8e0d1e3731841d44c34571b6c97f5b95e8296a45318b94e5287a6e", + "zh:b4c2ab35d1b7696c30b64bf2c0f3a62329107bd1a9121ce70683dec58af19615", + "zh:c43723e8cc65bcdf5e0c92581dcbbdcbdcf18b8d2037406a5f2033b1e22de442", + "zh:ceb5495d9c31bfb299d246ab333f08c7fb0d67a4f82681fbf47f2a21c3e11ab5", + "zh:e171026b3659305c558d9804062762d168f50ba02b88b231d20ec99578a6233f", + "zh:ed0fe2acdb61330b01841fa790be00ec6beaac91d41f311fb8254f74eb6a711f", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.7.2" + constraints = "~> 3.0" + hashes = [ + "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", + "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", + "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", + "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", + "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", + "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", + "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", + "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", + "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", + "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", + "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", + ] +} diff --git a/examples/aws-rds-privatelink/README.md b/examples/aws-rds-privatelink/README.md new file mode 100644 index 0000000..a338b72 --- /dev/null +++ b/examples/aws-rds-privatelink/README.md @@ -0,0 +1,34 @@ +# AWS RDI PrivateLink Demo + +This directory contains example Terraform to connect Redis Cloud RDI to an example Postgres source database. + +## Setup + +To use the example Terraform you must have: +- [Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) +- [AWS CLI](https://aws.amazon.com/cli/) +- [AWS credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) + +Run `terraform init` to initialize the Terraform repository. This is only necessary the first time you use the repo. + +## Usage + +Copy the values from the Redis Cloud RDI UI into `example.tfvars`. + +Run `terraform apply -var-file example.tfvars` + +## Connecting to the database + +You can connect to the postgres database directly from your laptop by running `./psql.sh`. + +## Tearing down + +Run `terraform destroy -var-file example.tfvars` to destroy the resources. + +## Submodules + +There are 3 submodules which can be reused: + +- `aws-rdi-quickstart-postgres` - creates a VPC, Security Group and EC2 instance running a demo Postgres database +- `aws-privatelink` - creates a Network Load Balancer and PrivateLink Service Endpoint to permit connectivity from Redis Cloud to the database +- `aws-secret-manager` - creates a Secret Manager secret with IAM permissions to work with Redis Cloud diff --git a/examples/aws-rds-privatelink/example.tfvars b/examples/aws-rds-privatelink/example.tfvars new file mode 100644 index 0000000..08335a4 --- /dev/null +++ b/examples/aws-rds-privatelink/example.tfvars @@ -0,0 +1,6 @@ +region = "us-east-1" +azs = ["use1-az2", "use1-az4", "use1-az6"] +port = 5432 +name = "rdi-rds" +redis_secrets_arn = "" +redis_privatelink_arn = "" diff --git a/examples/aws-rds-privatelink/inputs.tf b/examples/aws-rds-privatelink/inputs.tf new file mode 100644 index 0000000..6a50191 --- /dev/null +++ b/examples/aws-rds-privatelink/inputs.tf @@ -0,0 +1,36 @@ +variable "region" { + type = string +} + +variable "port" { + type = number +} + +variable "name" { + type = string +} + +variable "redis_secrets_arn" { + type = string + validation { + condition = var.redis_secrets_arn != "" + error_message = "redis_secrets_arn must be configured with the ARN from the UI" + } +} + +variable "redis_privatelink_arn" { + type = string + validation { + condition = var.redis_privatelink_arn != "" + error_message = "redis_privatelink_arn must be configured with the ARN from the UI" + } +} + +variable "ssh_key_name" { + type = string + default = null +} + +variable "azs" { + type = list(string) +} diff --git a/examples/aws-rds-privatelink/main.tf b/examples/aws-rds-privatelink/main.tf new file mode 100644 index 0000000..d153f9a --- /dev/null +++ b/examples/aws-rds-privatelink/main.tf @@ -0,0 +1,75 @@ +terraform { + required_version = ">= 1.5.7" + + backend "local" { + path = "producer/terraform.tfstate" + } + + required_providers { + random = { + source = "hashicorp/random" + version = "~> 3.0" + } + } +} + +provider "aws" { + # Configure the region for the resources + region = var.region +} + +# Create an RDI quickstart Postgres database on RDS +module "rdi_quickstart_postgres" { + source = "../../modules/aws-rds-chinook" + + identifier = var.name + db_password = random_password.pg_password.result + db_port = var.port + azs = var.azs +} + +module "rds_lambda" { + source = "../../modules/aws-rds-lambda" + + identifier = var.name + elb_tg_arn = module.privatelink.tg_arn + db_endpoint = module.rdi_quickstart_postgres.rds_endpoint + rds_arn = module.rdi_quickstart_postgres.rds_arn + db_port = var.port +} + +# Create an NLB and PrivateLink Endpoint Service which allows secure connection to the database from Redis Cloud. +# This has no targets but we will add a Lambda function to update the target. +module "privatelink" { + source = "../../modules/aws-privatelink" + + identifier = var.name + port = var.port + vpc_id = module.rdi_quickstart_postgres.vpc_id + subnets = module.rdi_quickstart_postgres.vpc_public_subnets + target_type = "ip" + targets = [] + security_groups = [module.rdi_quickstart_postgres.security_group_id] + allowed_principals = [var.redis_privatelink_arn] +} + +# Create a secret in AWS Secret Manager with the database credentials +module "secret_manager" { + source = "../../modules/aws-secret-manager" + + # Because Secret Manager secrets are soft-deleted, add a random suffix to make the name unique. + # Otherwise running multiple apply-destroy cycles will fail because of the names conflicting. + identifier = "${var.name}-${random_id.secret_suffix.hex}" + allowed_principals = [var.redis_secrets_arn] + username = "postgres" + password = random_password.pg_password.result +} + +resource "random_id" "secret_suffix" { + byte_length = 8 +} + +resource "random_password" "pg_password" { + length = 16 + special = false +} diff --git a/examples/aws-rds-privatelink/outputs.tf b/examples/aws-rds-privatelink/outputs.tf new file mode 100644 index 0000000..327d5b7 --- /dev/null +++ b/examples/aws-rds-privatelink/outputs.tf @@ -0,0 +1,35 @@ +output "vpc_endpoint_service_name" { + value = module.privatelink.vpc_endpoint_service_name + description = "The VPC Endpoint service name for the database, to be configured in Redis Cloud" +} + +output "secret_arn" { + value = module.secret_manager.secret_arn + description = "The Secret Manager secret ARN, to be configured in Redis Cloud" +} + +output "database" { + value = "chinook" + description = "The name of the Postgres reference database" +} + +output "port" { + value = var.port + description = "The port for the NLB" +} + +output "password" { + value = random_password.pg_password.result + sensitive = true + description = "The postgres password. This is not used for RDI setup, only to connect to the DB with psql" +} + +output "rds_arn" { + value = module.rdi_quickstart_postgres.rds_arn + sensitive = true + description = "The postgres RDS ARN" +} + +output "psql_host" { + value = module.privatelink.lb_hostname +} diff --git a/examples/aws-rds-privatelink/psql.sh b/examples/aws-rds-privatelink/psql.sh new file mode 100755 index 0000000..38a7c48 --- /dev/null +++ b/examples/aws-rds-privatelink/psql.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -euo pipefail + +psql "postgresql://postgres:$(terraform output -raw password)@$(terraform output -raw ec2_instance_hostname)/chinook" diff --git a/examples/aws-rds-privatelink/psql_setup.tf b/examples/aws-rds-privatelink/psql_setup.tf new file mode 100644 index 0000000..acf9e55 --- /dev/null +++ b/examples/aws-rds-privatelink/psql_setup.tf @@ -0,0 +1,15 @@ +resource "null_resource" "setup_chinook" { + provisioner "local-exec" { + environment = { + PGPASSWORD: nonsensitive(random_password.pg_password.result) + } + command = < mysql.log +EOF + } +} diff --git a/examples/aws-rds-privatelink/rds.tf b/examples/aws-rds-privatelink/rds.tf new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/aws-rds-privatelink/rds.tf @@ -0,0 +1 @@ + From a52f4886a0a6ecccf66a567cc6672de10e134e9e Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Thu, 20 Nov 2025 21:01:11 -0500 Subject: [PATCH 03/10] Add one-off run of lambda for setup --- examples/aws-rds-privatelink/psql_setup.tf | 3 +++ modules/aws-rds-chinook/main.tf | 12 ++++++++++++ modules/aws-rds-lambda/sns.tf | 10 ++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/examples/aws-rds-privatelink/psql_setup.tf b/examples/aws-rds-privatelink/psql_setup.tf index acf9e55..6f32cbc 100644 --- a/examples/aws-rds-privatelink/psql_setup.tf +++ b/examples/aws-rds-privatelink/psql_setup.tf @@ -1,4 +1,7 @@ resource "null_resource" "setup_chinook" { + depends_on = [ + module.rdi_quickstart_postgres + ] provisioner "local-exec" { environment = { PGPASSWORD: nonsensitive(random_password.pg_password.result) diff --git a/modules/aws-rds-chinook/main.tf b/modules/aws-rds-chinook/main.tf index e5f3c69..50fb868 100644 --- a/modules/aws-rds-chinook/main.tf +++ b/modules/aws-rds-chinook/main.tf @@ -9,6 +9,18 @@ resource "aws_rds_cluster" "postgresql" { skip_final_snapshot = true db_subnet_group_name = module.vpc.database_subnet_group_name vpc_security_group_ids = [aws_security_group.producer_sg.id] + db_instance_parameter_group_name = aws_db_parameter_group.default.name +} + +resource "aws_db_parameter_group" "default" { + name = var.identifier + family = "postgres17" + + parameter { + name = "rds.logical_replication" + value = "1" + apply_method = "pending-reboot" + } } resource "aws_rds_cluster_instance" "cluster_instances" { diff --git a/modules/aws-rds-lambda/sns.tf b/modules/aws-rds-lambda/sns.tf index f876e22..57813fa 100644 --- a/modules/aws-rds-lambda/sns.tf +++ b/modules/aws-rds-lambda/sns.tf @@ -37,8 +37,8 @@ resource "aws_sns_topic_subscription" "rdi_failover_subscription" { endpoint = aws_lambda_function.rdi_failover_lambda.arn } -resource "aws_db_event_subscription" "rds_instance_failover_event" { - name = "${var.identifier}-rds-instance-events" +resource "aws_db_event_subscription" "rds_cluster_failover_event" { + name = "${var.identifier}-rds-cluster-events" sns_topic = aws_sns_topic.rdi_failover_topic.arn event_categories = ["creation", "failover", "failure"] source_type = "db-cluster" @@ -46,6 +46,12 @@ resource "aws_db_event_subscription" "rds_instance_failover_event" { enabled = true } +action "aws_lambda_invoke" "initial" { + config { + function_name = aws_lambda_function.rdi_failover_lambda.function_name + } +} + resource "aws_lambda_permission" "with_sns" { statement_id = "AllowExecutionFromSNS" action = "lambda:InvokeFunction" From 99805025c318cb9fcb18b1d4a0a0876ec87621e5 Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Fri, 21 Nov 2025 08:18:38 -0500 Subject: [PATCH 04/10] fmt --- examples/aws-rds-privatelink/main.tf | 6 ++-- examples/aws-rds-privatelink/psql_setup.tf | 6 ++-- modules/aws-rds-chinook/main.tf | 40 +++++++++++----------- modules/aws-rds-chinook/output.tf | 4 +-- modules/aws-rds-chinook/security.tf | 26 +++++++------- modules/aws-rds-chinook/vpc.tf | 6 ++-- modules/aws-rds-lambda/inputs.tf | 6 ++-- modules/aws-rds-lambda/lambda.tf | 18 +++++----- modules/aws-rds-lambda/sns.tf | 28 +++++++-------- 9 files changed, 70 insertions(+), 70 deletions(-) diff --git a/examples/aws-rds-privatelink/main.tf b/examples/aws-rds-privatelink/main.tf index d153f9a..4a01355 100644 --- a/examples/aws-rds-privatelink/main.tf +++ b/examples/aws-rds-privatelink/main.tf @@ -32,10 +32,10 @@ module "rds_lambda" { source = "../../modules/aws-rds-lambda" identifier = var.name - elb_tg_arn = module.privatelink.tg_arn + elb_tg_arn = module.privatelink.tg_arn db_endpoint = module.rdi_quickstart_postgres.rds_endpoint - rds_arn = module.rdi_quickstart_postgres.rds_arn - db_port = var.port + rds_arn = module.rdi_quickstart_postgres.rds_arn + db_port = var.port } # Create an NLB and PrivateLink Endpoint Service which allows secure connection to the database from Redis Cloud. diff --git a/examples/aws-rds-privatelink/psql_setup.tf b/examples/aws-rds-privatelink/psql_setup.tf index 6f32cbc..4137689 100644 --- a/examples/aws-rds-privatelink/psql_setup.tf +++ b/examples/aws-rds-privatelink/psql_setup.tf @@ -1,10 +1,10 @@ resource "null_resource" "setup_chinook" { - depends_on = [ - module.rdi_quickstart_postgres + depends_on = [ + module.rdi_quickstart_postgres ] provisioner "local-exec" { environment = { - PGPASSWORD: nonsensitive(random_password.pg_password.result) + PGPASSWORD : nonsensitive(random_password.pg_password.result) } command = < Date: Fri, 21 Nov 2025 08:33:35 -0500 Subject: [PATCH 05/10] Update docs --- examples/aws-ec2-privatelink/main.tf | 2 +- examples/aws-rds-privatelink/README.md | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/aws-ec2-privatelink/main.tf b/examples/aws-ec2-privatelink/main.tf index 27b1d37..1ac7ff1 100644 --- a/examples/aws-ec2-privatelink/main.tf +++ b/examples/aws-ec2-privatelink/main.tf @@ -39,7 +39,7 @@ module "privatelink" { vpc_id = module.rdi_quickstart_postgres.vpc_id subnets = module.rdi_quickstart_postgres.vpc_public_subnets target_type = "instance" - target = module.rdi_quickstart_postgres.instance_id + targets = [module.rdi_quickstart_postgres.instance_id] security_groups = [module.rdi_quickstart_postgres.security_group_id] allowed_principals = [var.redis_privatelink_arn] } diff --git a/examples/aws-rds-privatelink/README.md b/examples/aws-rds-privatelink/README.md index a338b72..54a772d 100644 --- a/examples/aws-rds-privatelink/README.md +++ b/examples/aws-rds-privatelink/README.md @@ -1,6 +1,8 @@ -# AWS RDI PrivateLink Demo +# AWS RDI RDS PrivateLink Demo -This directory contains example Terraform to connect Redis Cloud RDI to an example Postgres source database. +This directory contains example Terraform to connect Redis Cloud RDI to an Aurora Postgres RDS database and handle failover. + +This blog post from AWS documents the architecture: https://aws.amazon.com/blogs/database/access-amazon-rds-across-vpcs-using-aws-privatelink-and-network-load-balancer/ ## Setup @@ -27,8 +29,9 @@ Run `terraform destroy -var-file example.tfvars` to destroy the resources. ## Submodules -There are 3 submodules which can be reused: +There are 4 submodules which can be reused: -- `aws-rdi-quickstart-postgres` - creates a VPC, Security Group and EC2 instance running a demo Postgres database +- `aws-rds-chinook` - creates a VPC, Security Group and RDS database with 2 instances +- `aws-rds-lambda` - creates a Lambda function to update the Load Balancer target group based on SNS events from RDS - `aws-privatelink` - creates a Network Load Balancer and PrivateLink Service Endpoint to permit connectivity from Redis Cloud to the database - `aws-secret-manager` - creates a Secret Manager secret with IAM permissions to work with Redis Cloud From f71b409339420ac2e9ee52af7fbce33208674a27 Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Fri, 21 Nov 2025 08:35:19 -0500 Subject: [PATCH 06/10] update psql.sh --- examples/aws-rds-privatelink/psql.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/aws-rds-privatelink/psql.sh b/examples/aws-rds-privatelink/psql.sh index 38a7c48..40ce1b4 100755 --- a/examples/aws-rds-privatelink/psql.sh +++ b/examples/aws-rds-privatelink/psql.sh @@ -2,4 +2,4 @@ set -euo pipefail -psql "postgresql://postgres:$(terraform output -raw password)@$(terraform output -raw ec2_instance_hostname)/chinook" +psql "postgresql://postgres:$(terraform output -raw password)@$(terraform output -raw psql_host)/chinook" From 48f542728e1ff5b5d408b400008811b398401aa2 Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Fri, 21 Nov 2025 08:35:43 -0500 Subject: [PATCH 07/10] Remove empty file --- examples/aws-rds-privatelink/rds.tf | 1 - 1 file changed, 1 deletion(-) delete mode 100644 examples/aws-rds-privatelink/rds.tf diff --git a/examples/aws-rds-privatelink/rds.tf b/examples/aws-rds-privatelink/rds.tf deleted file mode 100644 index 8b13789..0000000 --- a/examples/aws-rds-privatelink/rds.tf +++ /dev/null @@ -1 +0,0 @@ - From 6b13f9dc2ce11a32512f52a3a6b0442ce0414b2c Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Fri, 21 Nov 2025 12:25:29 -0500 Subject: [PATCH 08/10] Fix timing of initial lambda --- examples/aws-rds-privatelink/main.tf | 1 + examples/aws-rds-privatelink/psql_setup.tf | 3 ++- modules/aws-rds-lambda/sns.tf | 5 ++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/aws-rds-privatelink/main.tf b/examples/aws-rds-privatelink/main.tf index 4a01355..85e9da4 100644 --- a/examples/aws-rds-privatelink/main.tf +++ b/examples/aws-rds-privatelink/main.tf @@ -30,6 +30,7 @@ module "rdi_quickstart_postgres" { module "rds_lambda" { source = "../../modules/aws-rds-lambda" + depends_on = [module.rdi_quickstart_postgres] identifier = var.name elb_tg_arn = module.privatelink.tg_arn diff --git a/examples/aws-rds-privatelink/psql_setup.tf b/examples/aws-rds-privatelink/psql_setup.tf index 4137689..6590130 100644 --- a/examples/aws-rds-privatelink/psql_setup.tf +++ b/examples/aws-rds-privatelink/psql_setup.tf @@ -1,6 +1,7 @@ resource "null_resource" "setup_chinook" { depends_on = [ - module.rdi_quickstart_postgres + module.rdi_quickstart_postgres, + module.rds_lambda ] provisioner "local-exec" { environment = { diff --git a/modules/aws-rds-lambda/sns.tf b/modules/aws-rds-lambda/sns.tf index a3b8c2e..f350635 100644 --- a/modules/aws-rds-lambda/sns.tf +++ b/modules/aws-rds-lambda/sns.tf @@ -46,10 +46,9 @@ resource "aws_db_event_subscription" "rds_cluster_failover_event" { enabled = true } -action "aws_lambda_invoke" "initial" { - config { +resource "aws_lambda_invocation" "initial" { function_name = aws_lambda_function.rdi_failover_lambda.function_name - } + input = "{}" } resource "aws_lambda_permission" "with_sns" { From 626d0e5661c95c110d74252c5a218579c828e7f7 Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Fri, 21 Nov 2025 12:45:52 -0500 Subject: [PATCH 09/10] fmt --- examples/aws-rds-privatelink/main.tf | 4 ++-- modules/aws-rds-lambda/sns.tf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/aws-rds-privatelink/main.tf b/examples/aws-rds-privatelink/main.tf index 85e9da4..e92caa3 100644 --- a/examples/aws-rds-privatelink/main.tf +++ b/examples/aws-rds-privatelink/main.tf @@ -29,8 +29,8 @@ module "rdi_quickstart_postgres" { } module "rds_lambda" { - source = "../../modules/aws-rds-lambda" - depends_on = [module.rdi_quickstart_postgres] + source = "../../modules/aws-rds-lambda" + depends_on = [module.rdi_quickstart_postgres] identifier = var.name elb_tg_arn = module.privatelink.tg_arn diff --git a/modules/aws-rds-lambda/sns.tf b/modules/aws-rds-lambda/sns.tf index f350635..d1db5e8 100644 --- a/modules/aws-rds-lambda/sns.tf +++ b/modules/aws-rds-lambda/sns.tf @@ -47,8 +47,8 @@ resource "aws_db_event_subscription" "rds_cluster_failover_event" { } resource "aws_lambda_invocation" "initial" { - function_name = aws_lambda_function.rdi_failover_lambda.function_name - input = "{}" + function_name = aws_lambda_function.rdi_failover_lambda.function_name + input = "{}" } resource "aws_lambda_permission" "with_sns" { From 77acbdbf755ae55756c23ad7b2e12e12c003e55e Mon Sep 17 00:00:00 2001 From: Alysha Gardner <3100188+actgardner@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:27:40 -0500 Subject: [PATCH 10/10] Remove unused inputs and outputs --- examples/aws-rds-privatelink/inputs.tf | 5 ----- examples/aws-rds-privatelink/outputs.tf | 6 ------ 2 files changed, 11 deletions(-) diff --git a/examples/aws-rds-privatelink/inputs.tf b/examples/aws-rds-privatelink/inputs.tf index 6a50191..b4c214a 100644 --- a/examples/aws-rds-privatelink/inputs.tf +++ b/examples/aws-rds-privatelink/inputs.tf @@ -26,11 +26,6 @@ variable "redis_privatelink_arn" { } } -variable "ssh_key_name" { - type = string - default = null -} - variable "azs" { type = list(string) } diff --git a/examples/aws-rds-privatelink/outputs.tf b/examples/aws-rds-privatelink/outputs.tf index 327d5b7..7bfa46e 100644 --- a/examples/aws-rds-privatelink/outputs.tf +++ b/examples/aws-rds-privatelink/outputs.tf @@ -24,12 +24,6 @@ output "password" { description = "The postgres password. This is not used for RDI setup, only to connect to the DB with psql" } -output "rds_arn" { - value = module.rdi_quickstart_postgres.rds_arn - sensitive = true - description = "The postgres RDS ARN" -} - output "psql_host" { value = module.privatelink.lb_hostname }