.tf
和.tfstate
文件似乎都希望以纯文本格式存储MySQL密码。由团队维护。当.tf
中存在机密时,这种做法有何不同?可以完全加密这些值吗?关于.tfstate:
我可以在运行Terraform apply之后将
.tf
安全地存储在某处,但是这种用法会更好完全不存储的情况下?#1 楼
Terraform支持在调用期间添加带有变量的其他文件。文档:https://www.terraform.io/intro/getting-started/variables.html#from-a-file
我们正在使用该功能在每次Terraform调用时提供一个
secrets.tfvars
文件。我们还使用脚本来包装命令,以使命令的调用保持一致,并且所有团队成员都避免犯相同的错误。包装程序在执行之前将.tfstate
与S3同步,最后将.tfstate
推回S3。我还听说有人用领事存储在状态中做相同的事情,甚至在领事中添加了一种信号量以防止两个人同时启动Terraform。在variables.tf
文件中,它强制用户输入值。可以手动输入,也可以使用如上所述的-var-file
命令选项输入。不对您的机密设置默认值是执行需要更改机密的更改的好方法。secrets.tfvars
文件是指向其中一个未存储在版本控制中的机密文件的符号链接。 。我们每个环境都有几个,例如secrets-prod.tfvars
,secrets-dev.tfvars
,secrets-stg.tfvars
等。分享秘密的其他方式。由于当前机密信息的格式更改或机密信息本身,我们需要在版本控制渠道之外将其传达给团队-坦白说,这并不总是很好。但是秘密确实很少改变。#2 楼
我们避免使用Terraform处理我们的秘密。即使您如上所述设法通过var文件“ secrtes.tfvars”注入机密,这些机密也会存储在terraform(远程)状态。您可以保护远程状态文件通过使用例如S3授权,或者您可以gitignore本地状态文件,但我们决定不依赖这种保护。
评论
还要检查github.com/hashicorp/terraform/issues/516,这是他们跟踪tfstate泄露机密的问题的地方
– jottr
17-10-2在19:34
#3 楼
如果您使用的是AWS,请查看AWS Blog上Segment.io的“管理秘密的正确方法”。我们提倡对所有客户使用chamber
来管理机密。通过结合使用AWS Systems Manager参数存储(SSM)和KMS密钥来工作。这样可确保机密信息在静止(和传输)时进行加密,由IAM保护,可通过CloudTrails进行审核,并且仅在运行时作为环境变量公开。 配置腔室并设置KMS密钥后,我们将机密写入参数存储中。
chamber write db TF_VAR_DB_USER foobar
chamber write db TF_VAR_DB_PASS secret
然后在调用terraform时使用这些秘密。您的HCL代码中名为
DB_USER
和DB_PASS
的变量。 例如,您可以将其添加到
variables.tf
chamber exec db -- terraform plan
注意:
chamber
将始终以大写形式导出环境变量/>我们提供了一个名为terraform-aws-kms-key
的Terraform模块,以简化配置KMS密钥的过程。请查看我们的详细文档,并提供有关如何使用具有多个名称空间的chamber
以及如何使用带有Terraform的Chamber来管理机密的示例。请参阅我们完整的参考示例以了解供应室相关性。 对于
.tfstate
,您可以很好地说明状态文件中存在纯文本机密。真的没有办法解决这个问题。为了让terraform计算更改以构建计划,它需要知道“之前”和“之后”状态。因此,我们建议使用带有强制版本控制的加密S3存储桶。根据最佳实践,使用terraform-aws-tfstate-backend
模块配置存储区和DynamoDB锁定表。 评论
这与AWS服务紧密相关,AWS服务没有提到这个问题,而且听起来并不能真正解决内部基础架构或任何其他云。
–滕西拜
18年7月27日在8:21
@tensibai,您是正确的。最初的问题没有提供足够的信息来确定操作平台以做出最佳建议。每个平台都将取决于平台功能而有所不同。在prem或baremetal上,用户可能要考虑结合使用Vault和Terraform Enterprise。实施范围将大得多。 :)
–埃里克·奥斯特曼(Erik Osterman)
18年7月27日在20:42
我已经使用过AWS Secrets Manager,并且不想使用Chamber和Parameter Store。是否可以使用Secrets Manager做同样的事情?
– red888
19年1月21日在16:19
#4 楼
要将机密信息导入.tf文件,您还可以使用外部数据源。这可能是例如解密您秘密的脚本。评论
不利的一面是,任何具有依赖于外部数据源值的属性的资源都将被“计算”,因此即使机密未更改,每次运行也可能会被terraform修改。可能没问题,但在某些情况下可能要花一些时间或最坏的时间。
–达沃斯
20-2-6在10:52
#5 楼
我研究了几种不同的方式,但是在实现像Vault这样的更大的东西之前,我特别喜欢git-crypt做一个临时的事情。评论
要告诉谁投票,请解释原因。
– jottr
17-10-2在19:43
#6 楼
您可以利用外部数据源将机密信息导入Terraform并使用gpg
加密机密文件。例如,这是terraform文件在创建密码为
foobarbaz
的rds实例时需要的data "external" "rds" {
program = [ "cat", ".secrets/rds.json"]
}
resource "aws_db_instance" "default" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "mydb"
username = "foo"
password = "${data.external.rds.result.password}"
parameter_group_name = "default.mysql5.7"
}
您可以查看这篇文章,其中详细说明了如何执行此操作。
如何加密Terraform机密
#7 楼
您可以将值存储在参数存储中,并通过使用数据资源获取值在terraform资源中使用它们。data "aws_ssm_parameter" "rds_password" {
name = "/${var.project_name}/DB_PASSWORD"
}
resource "aws_db_instance" "rds" {
...
password = data.aws_ssm_parameter.rds_password.value
...
}
评论
链接到代码-gist.github.com/kesor/21f942be0350559b44f7ad1f9d846e7c
– Evgeny Zislis
17年4月3日在9:31