我有一个yaml文件,它类似于以下内容(仅供参考:ssm_secrets 可以是空数组):
rabbitmq:
repo_name: bitnami
namespace: rabbitmq
target_revision: 11.1.1
path: rabbitmq
values_file: charts/rabbitmq/values.yaml
ssm_secrets: []
app_name_1:
repo_name: repo_name_1
namespace: namespace_1
target_revision: target_revision_1
path: charts/path
values_file: values.yaml
ssm_secrets:
- name: name-dev-1
key: .env
ssm_path: ssm_path/dev
name-backend:
repo_name: repo_name_2
namespace: namespace_2
target_revision: target_revision_2
path: charts/name-backend
values_file: values.yaml
ssm_secrets:
- name: name-backend-app-dev
ssm_path: name-backend/app/dev
key: app.ini
- name: name-backend-abi-dev
ssm_path: name-backend/abi/dev
key: contractTokenABI.json
- name: name-backend-widget-dev
ssm_path: name-backend/widget/dev
key: name.ini
- name: name-abi-dev
ssm_path: name-abi/dev
key: name_1.json
- name: name-website-dev
ssm_path: name/website/dev
key: website.ini
- name: name-name-dev
ssm_path: name/name/dev
key: contract.ini
- name: name-key-dev
ssm_path: name-key/dev
key: name.pub
使用External Secrets和EKS Blueprints,我尝试生成创建Secrets所需的yaml文件
resource "kubectl_manifest" "secret" {
for_each = toset(flatten([for service in var.secrets : service.ssm_secrets[*].ssm_path]))
yaml_body = <<YAML
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: ${replace(each.value, "/", "-")}
namespace: ${split("/", each.value)[0]}
spec:
refreshInterval: 30m
secretStoreRef:
name: ${local.cluster_secretstore_name}
kind: ClusterSecretStore
data:
- secretKey: .env
remoteRef:
key: ${each.value}
YAML
depends_on = [kubectl_manifest.cluster_secretstore, kubernetes_namespace_v1.namespaces]
}
上面的工作正常,但我还需要将yaml中的key值用到**secretKey中:<key_value from yaml>。
如果我尝试for_each = toset(flatten([for service in var.secrets : service.ssm_secrets[*]]))
resource "kubectl_manifest" "secret" {
for_each = toset(flatten([for service in var.secrets : service.ssm_secrets[*]]))
yaml_body = <<YAML
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: ${replace(each.value["ssm_path"], "/", "-")}
namespace: ${split("/", each.value["ssm_path"])[0]}
spec:
refreshInterval: 30m
secretStoreRef:
name: ${local.cluster_secretstore_name}
kind: ClusterSecretStore
data:
- secretKey: .env
remoteRef:
key: ${each.value["ssm_path"]}
YAML
depends_on = [kubectl_manifest.cluster_secretstore, kubernetes_namespace_v1.namespaces]
}
它只是给了我以下错误:
给定的“for_each”参数值不合适:“for_each”支持Map和字符串集,但您提供了一个包含类型对象的集。
我试过将变量转换成Map,使用查找,但它不起作用。任何帮助将不胜感激。
更新1:
根据@MattSchuchard的建议,将for_each更改为for_each = toset(flatten([for service in var.secrets : service.ssm_secrets]))
出现以下错误:
Error: Invalid for_each set argument
│
│ on ../../modules/02-plugins/external-secrets.tf line 58, in resource "kubectl_manifest" "secret":
│ 58: for_each = toset(flatten([for service in var.secrets : service.ssm_secrets]))
│ ├────────────────
│ │ var.secrets is object with 14 attributes
│
│ The given "for_each" argument value is unsuitable: "for_each" supports maps and sets of strings, but you have provided a set containing type object.
更新二:
@mariux给出了完美的解决方案,但这是我想出的。它不是那么干净,但绝对有效(PS:我自己会使用Mariux的解决方案):
locals {
my_list = tolist(flatten([for service in var.secrets : service.ssm_secrets[*]]))
}
resource "kubectl_manifest" "secret" {
count = length(local.my_list)
yaml_body = <<YAML
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: ${replace(local.my_list[count.index]["ssm_path"], "/", "-")}
namespace: ${split("/", local.my_list[count.index]["ssm_path"])[0]}
spec:
refreshInterval: 30m
secretStoreRef:
name: ${local.cluster_secretstore_name}
kind: ClusterSecretStore
data:
- secretKey: ${local.my_list[count.index]["key"]}
remoteRef:
key: ${local.my_list[count.index]["ssm_path"]}
YAML
depends_on = [kubectl_manifest.cluster_secretstore, kubernetes_namespace_v1.namespaces]
}
2条答案
按热度按时间bq9c1y661#
假设
根据你分享的内容,我做出以下假设:
key
和ssm_path
属性通过ssm_secrets.*.name
创建外部机密。name
对于所有服务是全局唯一的并且从不被重用。terraform hacks
基于这些假设,您可以使用以下命令创建一个包含所有ssm_secrets的数组
并将其转换为可在
for_each
中使用的Map,方法是键入.name
的值:完整(工作)示例
下面的例子对我来说很有用,并假设了应该在哪里使用变量。
yamldecode
将原始输入解码为local.input
yamlencode
使阅读清单更容易,并删除一些字符串插值。这也确保了在我们将HCL转换为yaml时缩进是正确的。terraform init && terraform plan
将计划创建以下资源:提示:您也可以尝试使用
kubernetes_manifest
resource而不是kubectl_manifest
p.s.:我们创建了Terramate,使复杂的Terraform代码的创建变得更容易。但这似乎完全适合纯Terraform。
kh212irz2#
如果将
for_each
元参数修改为:那么
kubernetes_manifest.secret
资源中的lambda/闭包作用域迭代器变量(默认名称为each
)将是一个list(object)
类型,表示类似于YAML中的哈希列表(Kubernetes中的Map列表)的所需值,并且可以使用each.value["ssm_path"]
访问ssm_path
,使用each.value["key"]
访问key
。