我正在尝试使用AWS机密管理器来声明RDS管理员凭据。
- 在rds.tf中将变量RdsAdminCred中的凭据声明为键/值对
- 在同一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)
}
- 我不知道如何使用下面声明中的秘密字符串来替换用户名和密码的硬编码值
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"
任何帮助都将不胜感激。。
我会有一个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.result
}
然后,在数据库的单独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输出或打开状态文件(。
我建议使用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
}
variable "RdsAdminCred" {
default = {
username = "dbadmin"
password = "dbadmin#02avia"
}
type = map(string)
}
resource "aws_secretsmanager_secret" "RdsAdminCred" {
name = "RdsAdminCred"
}
resource "aws_secretsmanager_secret_version" "RdsAdminCred" {
secret_id = aws_secretsmanager_secret.RdsAdminCred.id
secret_string = jsonencode(var.RdsAdminCred)
}
在你创建了一个秘密之后,你需要从中获取数据
data "aws_secretsmanager_secret" "env_secrets" {
name = "RdsAdminCred"
depends_on = [
aws_secretsmanager_secret.RdsAdminCred
]
}
data "aws_secretsmanager_secret_version" "current_secrets" {
secret_id = data.aws_secretsmanager_secret.env_secrets.id
}
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 = jsondecode(data.aws_secretsmanager_secret_version.current_secrets.secret_string)["username"]
password = jsondecode(data.aws_secretsmanager_secret_version.current_secrets.secret_string)["password"]
}
在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
}
AWS地形AWS_db_instance资源有一个新功能可以轻松做到这一点。
您可以指定manage_master_user_password属性以启用使用Secrets Manager管理主密码。还可以通过指定manage_master_user_password属性并删除password属性(需要删除(来更新现有集群以使用Secrets Manager。
注意:默认情况下,秘密轮换是启用的,这意味着DB秘密将每周更新一次,如果不希望出现这种行为,请禁用此功能。
可以通过删除master_user_secret_KMS_key_id属性来使用默认帐户KMS密钥。
resource "aws_kms_key" "example" {
description = "Example KMS Key"
}
resource "aws_db_instance" "default" {
allocated_storage = 10
db_name = "mydb"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t3.micro"
manage_master_user_password = true
master_user_secret_kms_key_id = aws_kms_key.example.key_id
username = "foo"
parameter_group_name = "default.mysql5.7"
}
来源:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance