(远程)状态文件中的Terraform和cleartext密码

时间:2017-02-06 20:46:24

标签: terraform hashicorp-vault

在Terraform回购中有很多关于这个问题的Git问题,有很多有趣的评论,但截至目前我还没有找到解决这个问题的方法。

Terraform在tfstate文件中存储纯文本值,包括密码。

大多数用户需要远程存储它们,以便团队可以在同一个基础架构上同时工作,其中大多数用户将状态文件存储在S3中。

那你怎么隐藏你的密码?

这里有没有人使用Terraform进行制作?你用明文保存密码吗? 您是否有特殊的工作流程来删除或隐藏它们?当你运行terraform apply时会发生什么?

我考虑过以下选项:

  • 将它们存放在Consul中 - 我不使用Consul
  • 从状态文件中删除它们 - 这需要每次执行另一个进程,我不知道Terraform如何处理具有空/不可读/不可用密码的资源
  • 存储随后更改的默认密码(因此Terraform将在tfstate文件中具有无效密码) - 与上述相同
  • 使用Vault资源 - 听起来它还不是一个完整的工作流程
  • 使用git-repo-crypt将它们存储在Git中 - Git也不是选项
  • 全局加密S3存储桶 - 如果他们可以访问AWS作为“经理”级别,这不会阻止人们看到纯文本密码,但它似乎是目前为止的最佳选择

从我的观点来看,这是我想看到的:

  • 状态文件不包含密码
  • 状态文件已加密
  • 状态文件中的密码是指向其他资源的“指针”,例如“vault:backend-type:/ path / to / password”
  • 每次Terraform运行都会从指定的提供商
  • 收集所需的密码

这只是一个愿望。

但是回到这个问题 - 你如何在生产中使用Terraform?

2 个答案:

答案 0 :(得分:5)

我想知道如何处理最佳做法,但让我分享一下我的案例,尽管这是对AWS的有限方式。基本上我不管理Terraform的凭证。

  • 设置RDS的初始密码,忽略生命周期钩子的差异并稍后更改。忽略差异的方法如下:

     resource "aws_db_instance" "db_instance" {
       ...
       password = "hoge"
    
       lifecycle {
         ignore_changes = ["password"]
       }
     }
    
  • IAM用户由Terraform管理,但IAM登录配置文件包括密码。我认为IAM密码应由个人管理,而不是由管理员管理。

  • 应用程序使用的API密钥也不受Terraform管理。它们使用AWS KMS(密钥管理服务)加密,加密数据保存在应用程序的git存储库或S3存储桶中。 KMS加密的优点是解密权限可以由IAM角色控制。无需管理密钥进行解密。

  • 虽然我还没有尝试过,但最近我注意到aws ssm put-parameter --key-id可以用作支持KMS加密的简单键值存储,所以这也是一个不错的选择。

    < / LI>

我希望这会对你有所帮助。

答案 1 :(得分:3)

整个远程状态的东西是being reworked for 0.9,它应该打开整个州档案的locking of remote statepotentially encrypting /只是秘密。

在此之前,我们只需使用多个AWS账户,并将进入该账户的资料写入该账户中的S3存储桶。在我们的案例中,我们并不太关心最终存在的秘密,因为如果您有权阅读存储桶,那么您通常在该帐户中拥有相当多的访问权限。另外,我们在状态文件中保存的唯一真实秘密是RDS数据库密码,我们将安全组级别的访问限制为仅应用程序实例和构建所有内容的Jenkins实例,因此无法从命令行直接访问人员无论如何,工作站。

我还建议在S3存储桶上添加静态加密(因为它基本上是免费的)和版本控制,以便您可以在必要时检索旧的状态文件。

更进一步,如果您担心对包含状态的S3存储桶具有读访问权限的人,您可以添加明确拒绝来自某些列入白名单的角色/用户的任何人访问的存储桶策略,然后将其考虑在内超越任何IAM访问权限。从related AWS blog post扩展示例我们可能有一个看起来像这样的存储桶策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::MyTFStateFileBucket",
        "arn:aws:s3:::MyTFStateFileBucket/*"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:userId": [
            "AROAEXAMPLEID:*",
            "AIDAEXAMPLEID"
          ]
        }
      }
    }
  ]
}

其中AROAEXAMPLEID表示示例角色ID,AIDAEXAMPLEID表示示例用户ID。这些可以通过运行:

找到
aws iam get-role -–role-name ROLE-NAME

aws iam get-user -–user-name USER-NAME

分别

如果您真的想完全加密状态文件,那么您需要编写一个包装脚本,使Terraform在本地(而不是远程)与状态文件交互,然后让您的包装脚本管理远程状态,在上传到S3之前加密它并在它被拉动时对其进行解密。