【问题标题】:terraform-kubernetes-provider how to create secret from file?terraform-kubernetes-provider 如何从文件中创建秘密?
【发布时间】: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 的顶级字段写入机密,并且当我将其挂载时,它不适用于其他资源。

这里有什么诀窍?

【问题讨论】:

    标签: kubernetes terraform terraform-template-file


    【解决方案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 中重新编码。所以我想目前没有二进制文件的解决方案...... 我将使用接下来找到的二进制文件进行编辑。

    【解决方案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 提供程序,我意识到了这一点。

      步骤很简单:

      1. 通过调用外部程序加载data
      2. 参考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)作为机密值?
            猜你喜欢
            • 2021-10-26
            • 2023-01-20
            • 2021-02-12
            • 2020-06-08
            • 2019-05-07
            • 2018-02-03
            • 2020-12-04
            • 2021-12-04
            • 2020-12-27
            相关资源
            最近更新 更多