Terraform RDS 数据库凭据

如何解决Terraform RDS 数据库凭据

我正在尝试使用 AWS Secrets Manager 来声明 RDS 管理员凭证。

  1. 在变量 RdsAdminCred 中将 rds.tf 中的凭据声明为键/值对
  2. 也在同一个 tf 文件中声明了机密
variable "RdsAminCred" {
    default = {
        username = "dbadmin"
        password = "dbadmin#02avia"
    }
    type = map(string)
}

resource "aws_secretsmanager_secret" "RdsAminCred" {
  name = "RdsAminCred"
}
resource "aws_secretsmanager_secret_version" "RdsAminCred" {
  secret_id     = aws_secretsmanager_secret.RdsAminCred.id
  secret_string = jsonencode(var.RdsAminCred)
}
  1. 我不确定如何使用下面声明中的秘密字符串来替换用户名和密码的硬编码值。
resource "aws_db_instance" "default" {
  identifier            = "testdb"
  allocated_storage    = 20
  storage_type         = "gp2"
  engine               = "MysqL"
  engine_version       = "5.7"
  instance_class       = "db.t2.medium"
  name                 = "mydb"
 
  username             = "dbadmin"
  password             = "dbadmin#01avia"

感谢任何帮助..

解决方法

在您的 Terraform 代码中,您可以使用 aws_secretsmanager_secret_version 数据源读取此机密:

data "aws_secretsmanager_secret_version" "creds" {
  # write your secret name here
  secret_id = "your_secret"
}

使用 jsondecode 从 JSON 解析秘密:

locals {
  your_secret = jsondecode(
    data.aws_secretsmanager_secret_version.creds.secret_string
  )
}

现在将秘密传递给 RDS:

resource "aws_db_instance" "example" {
  engine               = "engine"
  engine_version       = "version"
  instance_class       = "instance"
  name                 = "example"
  # Set the secrets from AWS Secrets Manager
  username = local.your_secret.username
  password = local.your_secret.password
}
,

我建议改用 random_password 资源。然后您可以在集群配置和机密管理器中引用它。

示例:

resource "random_password" "master_password" {
  length  = 16
  special = false
}

resource "aws_rds_cluster" "default" {
  cluster_identifier = "my-cluster"
  
  master_username = "admin"
  master_password = random_password.default_master_password.result

  # other configurations
  # .
  # .
  # .
}

resource "aws_secretsmanager_secret" "rds_credentials" {
  name = "credentials"
}

resource "aws_secretsmanager_secret_version" "rds_credentials" {
  secret_id     = aws_secretsmanager_secret.rds_credentials.id
  secret_string = <<EOF
{
  "username": "${aws_rds_cluster.default.master_username}","password": "${random_password.master_password.result}","engine": "mysql","host": "${aws_rds_cluster.default.endpoint}","port": ${aws_rds_cluster.default.port},"dbClusterIdentifier": "${aws_rds_cluster.default.cluster_identifier}"
}
EOF
}
,

我会有一个 TF 配置来设置您的秘密并将其存储在 AWS Secrets Manager 中,就像这样。

resource "random_password" "master"{
  length           = 16
  special          = true
  override_special = "_!%^"
}

resource "aws_secretsmanager_secret" "password" {
  name = "test-db-password"
}

resource "aws_secretsmanager_secret_version" "password" {
  secret_id = aws_secretsmanager_secret.password.id
  secret_string = random_password.master
}

然后在您的数据库的单独 TF 配置中,您可以使用来自 AWS Secrets Manager 的密钥。

data "aws_secretsmanager_secret" "password" {
  name = "test-db-password"

}

data "aws_secretsmanager_secret_version" "password" {
  secret_id = data.aws_secretsmanager_secret.password
}

resource "aws_db_instance" "default" {
  identifier            = "testdb"
  allocated_storage    = 20
  storage_type         = "gp2"
  engine               = "mysql"
  engine_version       = "5.7"
  instance_class       = "db.t2.medium"
  name                 = "mydb"
 
  username             = "dbadmin"
  password             = data.aws_secretsmanager_secret_version.password

在上面的评论中,Asri Badlah 建议在控制台中手动输入密码。我想你可以做到这一点。然而,这种方法确实开始偏离 IaC 的基本原则 - 将所有内容置于源代码控制中。当然,您不想将密码、私钥等检查到源代码管理中。但在这里,你可以看到我们没有这样做。我们用一个配置填充一个秘密,并用另一个配置使用它。这确保代码可以被签入源代码管理,但密码不能。

就状态而言,密码确实会在 TF 状态下存储和解密。但是,如果您使用适当的状态管理,这应该不是问题。理想情况下,您会希望使用远程状态、加密和限制访问。

最后一点,我不会像 Evan Closson 建议的那样只使用 random_password。这种方法意味着您的数据库密码 100% 由 Terraform 管理。通过使用 Secrets Manager,您的密码由服务管理,这意味着您可以执行其他操作,例如轮换密码(未显示)和检索密码,而无需依赖 Terraform(例如 terraform 输出或破解状态文件) .

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?