Я использую 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, и когда я смонтирую его, он не будет работать с другими ресурсами.
В чем здесь хитрость?

В основном вам нужно предоставить карту следующим образом:
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}"
}
}
Кажется, если запустить команду 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/901
Просто используйте 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.
Шаги довольно просты:
data, вызвав внешнюю программу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
извините за понижение, но это не касается вопроса: как добавить файл (возможно, не UTF-8) в качестве значения секрета с помощью Terraform?