Terraform-kubernetes-provider как создать секрет из файла?

Я использую terraform kubernetes-провайдер и хочу перевести что-то вроде этой команды kubectl в TF:

kubectl create secret generic my-secret --from-file mysecret.json

Однако кажется, что поле secret ресурса dataожидает только карту TF.

Я пробовал что-то вроде

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, и когда я смонтирую его, он не будет работать с другими ресурсами.

В чем здесь хитрость?

Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
12
0
8 744
6

Ответы 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}"
      }
    }

извините за понижение, но это не касается вопроса: как добавить файл (возможно, не UTF-8) в качестве значения секрета с помощью Terraform?

Francesco Gualazzi 19.11.2019 12:07

Кажется, если запустить команду 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

он сохраняет его аналогично имени файла в качестве единственного ключа. Когда я монтирую это в том/volumeMount, он работает, как и ожидалось. Я боялся, что этого не произойдет, но когда я создаю секрет с помощью аргумента --from-file, он именно так его и хранит.

пока файл закодирован в 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")
      }
    }

Если файл является двоичным, у вас будет такая ошибка, как

Call to function "file" failed: contents of /your/relative/path/to/file.txt are not valid UTF-8; use the filebase64 function to obtain the Base64 encoded contents or the other file functions (e.g. filemd5, filesha256) to obtain file hashing results instead.

Я попытался закодировать файл в base64, но проблема в том, что полученный текст будет перекодирован в base64 провайдером. Так что я думаю, что на данный момент нет решения для двоичных файлов... Я отредактирую то, что найду дальше для двоичных файлов.

связанная проблема: github.com/hashicorp/terraform-provider-kubernetes/issues/90‌​1

LandoR 20.11.2020 12:41

Просто используйте 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")}"
  }
}

Это может быть немного не по теме, но я столкнулся с похожей проблемой, за исключением того, что файл может отсутствовать, и в этом случае terraform [plan|apply] терпит неудачу.

Если быть точным: мне нужно было продублировать секрет из одного пространства имен в другое.

Я понял это, используя провайдера hashicorp/external.

Шаги довольно просты:

  1. Загрузите data, вызвав внешнюю программу
  2. Обратитесь к ресурсу data в kubernetes_secret

Программа должна принимать (и обрабатывать) JSON на STDIN и создавать действительный JSON на STDOUT в качестве ответа на параметры, переданные в JSON STDIN.

Пример сценария оболочки:

#!/bin/bash

set -e

/bin/echo -n '{ "token": "'
kubectl get -n consul secrets/hashicorp-consul-bootstrap-acl-token --template = {{.data.token}}
/bin/echo -n '"}'

источник тарраформа:


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"
    }
  }
}

Я считаю, что теперь вы можете использовать атрибут binary_data в секрете. например

binary_data = {
    "my_payload.bin" = "${filebase64("${path.module}/my_payload.bin")}"
}

ссылка: https://github.com/hashicorp/terraform-provider-kubernetes/pull/1228https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret#binary_data

Другие вопросы по теме