无法在本地连接到 RDS Aurora DB

Unable to connect to RDS Aurora DB locally

我对云架构有一些基本的了解,我想我会尝试在 Terraform 中启动一个 PostgreSQL 数据库。我正在使用 Secret Manager 来存储凭据...

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

还有一个 AuoraDB 实例,应该 可以使用以下代码公开访问


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 
}

当我 terraform apply 这样做时,一切都按预期创建,但是当我 运行 psql -h <ENDPOINT_TO_CLUSTER> 时,系统提示我输入 admin 的密码。转到秘密门户复制密码并输入收益率:

FATAL:  password authentication failed for user "admin"

同样,如果我尝试:

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

系统如预期提示我输入 db_user 的密码,得到:

psql: FATAL:  database "db_user" does not exist

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

您正在执行名为 data.aws_secretsmanager_secret_version.credentials 的数据查找,但您没有为此显示 Terraform 代码。 Terraform 将在 更新 aws_secretsmanager_secret_version 之前 进行查找。因此,它配置数据库的用户名和密码将从以前版本的秘密中提取,而不是您在 运行 apply.

时创建的新版本

您永远不应在 Terraform 中同时使用 dataresource 来指代同一事物。如果有 resource,请始终使用它,并且仅将 data 用于未由 Terraform 管理的内容。

由于您在 Terraform 代码中拥有资源本身(以及 random_password 资源),因此您根本不应该使用 data 查找。如果您从其中一个资源中提取值,那么 Terraform 将正确处理 creation/updates 的顺序。

例如:

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"]

或者只是简化它并去掉 jsondecode 步骤:

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

我还建议添加一些 Terraform 输出来帮助您诊断此类问题。以下内容将让您准确了解 Terraform 应用于数据库的用户名和密码:

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

output "db_password" {
  value = aws_rds_cluster.cluster-demo.master_password
  sensitive = true
}