terraform-kubernetes-provider 如何从文件中创建秘密?
Posted
技术标签:
【中文标题】terraform-kubernetes-provider 如何从文件中创建秘密?【英文标题】:terraform-kubernetes-provider how to create secret from file? 【发布时间】:2019-08-16 01:38:11 【问题描述】:我正在使用 terraform kubernetes-provider,我想将类似 kubectl
的命令翻译成 TF:
kubectl create secret generic my-secret --from-file mysecret.json
似乎,但是secret
资源的data
字段expects only a TF map。
我尝试过类似的东西
data "template_file" "my-secret"
template = "$file("$path.module/my-secret.json")"
resource "kubernetes_secret" "sgw-config"
metadata
name = "my-secret"
type = "Opaque"
data = "data.template_file.my-secret.template"
但它抱怨说这不是地图。所以,我可以这样做:
data =
"my-secret.json" = "data.template_file.my-secret.template"
但这将使用名为my-secret.json
的***字段写入机密,并且当我将其挂载时,它不适用于其他资源。
这里有什么诀窍?
【问题讨论】:
【参考方案1】:只要文件是 UTF-8 编码的,你就可以使用类似的东西
resource "kubernetes_secret" "some-secret"
metadata
name = "some-secret"
namespace = kubernetes_namespace.some-ns.metadata.0.name
labels =
"sensitive" = "true"
"app" = "my-app"
data =
"file.txt" = file("$path.cwd/your/relative/path/to/file.txt")
如果文件是二进制文件,则会出现类似的错误
调用函数“文件”失败:内容 /your/relative/path/to/file.txt 不是有效的 UTF-8;使用 filebase64 函数获取 Base64 编码的内容或其他 文件函数(例如 filemd5、filesha256)以获得文件散列 结果。
我尝试在 base64 中对文件进行编码,但问题是生成的文本将由提供者在 base64 中重新编码。所以我想目前没有二进制文件的解决方案...... 我将使用接下来找到的二进制文件进行编辑。
【讨论】:
相关问题:github.com/hashicorp/terraform-provider-kubernetes/issues/901【参考方案2】:只需使用 https://www.terraform.io/docs/providers/kubernetes/r/config_map.html#binary_data
resource "kubernetes_config_map" "example"
metadata
name = "my-config"
binary_data =
"my_payload.bin" = "$filebase64("$path.module/my_payload.bin")"
【讨论】:
【参考方案3】:这可能有点跑题了,但我也遇到过类似的问题,只是文件可能不存在,在这种情况下terraform [plan|apply]
失败。
确切地说:我需要将秘密从一个命名空间复制到另一个命名空间。
通过使用hashicorp/external
提供程序,我意识到了这一点。
步骤很简单:
-
通过调用外部程序加载
data
参考kubernetes_secret
资源中的data
程序应该接受(并处理)STDIN 上的 JSON,并在 STDOUT 上生成有效的 JSON 作为对在 STDIN 的 JSON 中传入的参数的响应。
示例 shell 脚本:
#!/bin/bash
set -e
/bin/echo -n ' "token": "'
kubectl get -n consul secrets/hashicorp-consul-bootstrap-acl-token --template=.data.token
/bin/echo -n '"'
tarraform 来源:
data "external" "token"
program = ["sh", "$path.module/consul-token.sh"]
resource "kubernetes_secret" "consul-token"
depends_on = [data.external.token]
metadata
name = "consul-token"
namespace = "app"
data =
token = base64decode(data.external.token.result.token)
和要求:
terraform
required_providers
external =
source = "hashicorp/external"
version = ">= 2.0.0"
【讨论】:
【参考方案4】:我相信你现在可以在秘密中使用 binary_data 属性了。 例如
binary_data =
"my_payload.bin" = "$filebase64("$path.module/my_payload.bin")"
参考: https://github.com/hashicorp/terraform-provider-kubernetes/pull/1228 https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret#binary_data
【讨论】:
【参考方案5】:看来如果你运行命令kubectl create secret generic my-secret --from-file mysecret.json
然后
$ kubectl get secrets my-secret -o yaml
apiVersion: v1
data:
my-secret.json: ewogICA.....
kind: Secret
metadata:
creationTimestamp: "2019-03-25T18:20:43Z"
name: my-secret
namespace: default
resourceVersion: "67026"
selfLink: /api/v1/namespaces/default/secrets/my-secret
uid: b397a29c-4f2a-11e9-9806-000c290425d0
type: Opaque
它以文件名作为单个键类似地存储它。当我将它安装在卷/卷安装中时,它按预期工作。我担心它不会,但是当我使用 --from-file
参数创建秘密时,这正是它存储它的方式。
【讨论】:
【参考方案6】:基本上你需要提供这样的地图:
resource "kubernetes_secret" "sgw-config"
metadata
name = "my-secret"
type = "Opaque"
data
"key1" = "value1"
"key2" = "value2"
您可以使用
引用您的内部变量resource "kubernetes_secret" "sgw-config"
metadata
name = "my-secret"
type = "Opaque"
data
"USERNAME" = "$var.some_variable"
"PASSWORD" = "$random_string.root_password.result"
【讨论】:
很抱歉投反对票,但这并没有解决问题:如何使用 Terraform 添加文件(可能非 UTF-8)作为机密值?以上是关于terraform-kubernetes-provider 如何从文件中创建秘密?的主要内容,如果未能解决你的问题,请参考以下文章