Home > Blockchain >  Unable to connect to RDS Aurora DB locally
Unable to connect to RDS Aurora DB locally

Time:01-31

I have a somewhat basic understanding of Cloud Architecture and thought I would try to spin up a PostgreSQL DB in Terraform. I am using Secret Manager to store credentials...

resource "random_password" "password" {
  length           = 16
  special          = true
  override_special = "_%@"
}

resource "aws_secretsmanager_secret" "secret" {
  name = "admin"
  description = "Database admin user password"
}

resource "aws_secretsmanager_secret_version" "version" {
  secret_id = aws_secretsmanager_secret.secret.id
  secret_string = <<EOF
   {
    "username": "db_user",
    "password": "${random_password.password.result}"
   }
EOF
}

locals {
  db_credentials = jsondecode(data.aws_secretsmanager_secret_version.credentials.secret_string)
}

And an AuoraDB instance which should be publically accessible with the following code


resource "aws_rds_cluster" "cluster-demo" {
  cluster_identifier = "aurora-cluster-demo"
  database_name = "test_db"
  master_username = local.db_credentials["username"]
  master_password = local.db_credentials["password"]
  port = 5432
  engine = "aurora-postgresql"
  engine_version = "12.7"
  apply_immediately = true
  skip_final_snapshot  = "true"
}

// child instances inherit the same config
resource "aws_rds_cluster_instance" "cluster_instance" {
  identifier         = "aurora-cluster-demo-instance"
  cluster_identifier = aws_rds_cluster.cluster-demo.id
  engine             = aws_rds_cluster.cluster-demo.engine
  engine_version     = aws_rds_cluster.cluster-demo.engine_version
  instance_class     = "db.r4.large"
  publicly_accessible = true   # Remove 
}

When I terraform apply this, everything gets created as expected, but when I run psql -h <ENDPOINT_TO_CLUSTER> I get prompted to enter the password for admin. Going to the secrets portal copying the password and entering yields:

FATAL:  password authentication failed for user "admin"

Similarily, if I try:

psql --username=db_user --host=<ENDPOINT_TO_CLUSTER> --port=5432

I am prompted as expected, to enter the password for db_user, which yields:

psql: FATAL:  database "db_user" does not exist

Edit 1

secrets.tf

resource "random_password" "password" {
  length           = 16
  special          = true
  override_special = "_%@"
}

resource "aws_secretsmanager_secret" "secret" {
  name = "admin"
  description = "Database admin user password"
}

resource "aws_secretsmanager_secret_version" "version" {
  secret_id = aws_secretsmanager_secret.secret.id
  secret_string = <<EOF
   {
    "username": "db_user",
    "password": "${random_password.password.result}"
   }
EOF
}

database.tf

resource "aws_rds_cluster" "cluster-demo" {
  cluster_identifier = "aurora-cluster-demo"
  database_name = "test_db"
  master_username = "db_user"
  master_password = random_password.password.result
  port = 5432
  engine = "aurora-postgresql"
  engine_version = "12.7"
  apply_immediately = true
  skip_final_snapshot  = "true"
}

// child instances inherit the same config
resource "aws_rds_cluster_instance" "cluster_instance" {
  identifier         = "aurora-cluster-demo-instance"
  cluster_identifier = aws_rds_cluster.cluster-demo.id
  engine             = aws_rds_cluster.cluster-demo.engine
  engine_version     = aws_rds_cluster.cluster-demo.engine_version
  instance_class     = "db.r4.large"
  publicly_accessible = true   # Remove 
}

output "db_user" {
  value = aws_rds_cluster.cluster-demo.master_username
}

CodePudding user response:

You're doing a data lookup named data.aws_secretsmanager_secret_version.credentials but you don't show the Terraform code for that. Terraform is going to do that lookup before it updates the aws_secretsmanager_secret_version. So the username and password it is configuring the DB with is going to be pulled from the previous version of the secret, not the new version you are creating when you run apply.

You should never have both a data and a resource in your Terraform that refer to the same thing. Always use the resource if you have it, and only use data for things that aren't being managed by Terraform.

Since you have the resource itself available in your Terraform code (and also the random_password resource), you shouldn't be using a data lookup at all. If you pull the value from one of the resources, then Terraform will handle the order of creation/updates correctly.

For example:

locals {
  db_credentials = jsondecode(aws_secretsmanager_secret_version.version.secret_string)
}

resource "aws_rds_cluster" "cluster-demo" {
  master_username = local.db_credentials["username"]
  master_password = local.db_credentials["password"]

Or just simplify it and get rid of the jsondecode step:

resource "aws_rds_cluster" "cluster-demo" {
  master_username = "db_user"
  master_password = random_password.password.result

I also suggest adding a few Terraform outputs to help you diagnose this type of issue. The following will let you see exactly what username and password Terraform applied to the database:

output "db_user" {
  value = aws_rds_cluster.cluster-demo.master_username
}

output "db_password" {
  value = aws_rds_cluster.cluster-demo.master_password
  sensitive = true
}
  •  Tags:  
  • Related