如何从外部程序隐藏AWS凭证?

时间:2019-10-18 21:00:56

标签: terraform amazon-iam terraform-provider-aws

在我的情况下,我试图隐藏通过输出打印的aws访问键和秘密访问键。

我试图实现一个解决方案,但不幸的是,它在计划中打印了凭据。因此,每当我将代码/提交到GITHUB时,Jenkins中都会运行terraform,它会在GITHUB中吐出计划,从而暴露terraform计划中的凭据。

尽管我已经隐藏了输出,但是现在我将其打印在计划中并在GitHub中公开。我还尝试在输出中使用sensitive:true,可以轻松解决此问题。但是我的团队想要实施此解决方案:(

resource "aws_iam_access_key" "key" {
  user = "${aws_iam_user.user.name}"
}

resource "null_resource" "access_key_shell" {
  triggers = {
    aws_user = "${aws_iam_user.user.name}" // triggering an alert on the user, since if we pass aws_iam_access_key, access key is visible in plan.
  }
}

data "external" "stdout" {
  depends_on = ["null_resource.access_key_shell"]
  program    = ["sh", "${path.module}/read.sh"]

  query {
    access_id = "${aws_iam_access_key.key.id}"
    secret_id = "${aws_iam_access_key.key.secret}"
  }
}

resource "null_resource" "contents_access" {
  triggers = {
    stdout = "${lookup(data.external.logstash_stdout.result, "access_key")}"
    value  = "${aws_iam_access_key.key.id}"
  }
}

output "aws_iam_podcast_logstash_access_key" {
  value = "${chomp(null_resource.contents_access.triggers["stdout"])}"
}

read.sh

#!/bin/bash
set -eux
echo {\"access_key\":\"$(aws kms encrypt --key-id alias/amp_key --plaintext ${access_id}  --output text --query CiphertextBlob)\", > sample.json && echo \"secret_key\": \"$(aws kms encrypt --key-id alias/amp_key --plaintext ${secret_id} --output text --query CiphertextBlob)\"} >> sample.json
cat sample.json | jq -r '.access_key'
cat sample.json | jq -r '.secret_key'

我的地形计划:

<= data.external.stdout
      id:                <computed>
      program.#:         "2"
      program.0:         "sh"
      program.1:         "/Users/xxxx/projects/tf_iam_stage/read.sh"
      query.%:           "2"
      query.access_id:   "xxxxxxxx"  ----> I want to hide these values from the plan
      query.secret_id:   "xxxxxxxxxxxxxxxxxxxxxx/x" ----> I want to hide these values from the plan
      result.%:          <computed>

任何帮助! 预先感谢!

2 个答案:

答案 0 :(得分:0)

在您的情况下,如果您愿意采用Remote State的方法,那就太好了。

Remote State允许Terraform将状态存储在远程存储中。 Terraform支持将状态存储在Terraform Enterprise,Consul,S3等地方。

设置是在AWS S3上创建一个存储桶,除将要用于Terraform的用户外,任何人都不应读取或写入该存储桶。

我添加的代码是;

 terraform {
    backend "s3" {
      bucket = "my-new-bucket"
      key = "state/key"
      region = "eu-west-1"
    }
  }

这只是告诉Terraform使用S3作为后端提供程序来执行诸如存储tfstate文件的操作。

不要忘记运行terraform init,因为这是一项要求,Terraform会注意到您已从本地存储更改为存储在S3中。

完成后,您可以安全地删除本地tfstate文件,前提是您的详细信息已安全存储在S3中。

以下是一些有用的文档:Click docs

第二种方法是在此处使用Terraform plugin更多信息:Terraform plugin

祝你好运!

答案 1 :(得分:0)

这里发生了几件事。

首先,您泄漏了凭据,因为您将.tfstate存储在GitHub中。这是一个简单的解决方案。首先,将*.tfstate添加到您的.gitignore中,然后设置一个远程后端,如果您使用的是S3,则要签出策略和ACL以防止公共访问。

第二,另一个问题是您正在运行时获取凭据,除非您添加敏感标志,否则在运行时Terraform将显示​​所有内容。因此,基本上,如果您想采用这种方法,无论团队怎么说,都必须使用sensitive: true。但是,为什么以这种方式获取凭据?为什么不使用这些凭据添加新的提供程序,为该提供程序设置别名,而仅将其用于那些密钥所在的资源?