为Vault 'agent-inject-template'注解添加export选项时触发报错求助
问题:更新Vault Agent注入模板支持export环境变量
当前环境与配置
- Kubernetes版本:1.21
- 当前用于生成Vault注解的Helm模板:
{{- range $value := $.Values.vault.secrets }} {{- $secretName := regexFind "[^/]+$" $value }} vault.hashicorp.com/agent-inject-secret-{{ $secretName }}: {{ $value | quote }} vault.hashicorp.com/agent-inject-template-{{ $secretName }}: | {{`{{- with secret `}}{{ $value | quote }}{{` -}} {{ .Data.data | toJSON }} {{- end }}`}} {{- end }}
- 当前values.yaml配置:
vault: enabled: true secrets: - path/to/secret/database
- 生成的
/vault/secrets/database内容:
{"host":"example.us-east-1.rds.amazonaws.com","port":5432,"user":"postgres"}
尝试的修改
为了支持export环境变量,对Helm模板和values.yaml做了如下修改:
- 修改后的Helm模板:
{{- range $value := $.Values.vault.secrets }} {{- $secretName := regexFind "[^/]+$" .path }} vault.hashicorp.com/agent-inject-template-{{ $secretName }}: | {{`{{- with secret `}}{{ .path | quote }}{{` -}} {{ .Data.data | toJSON }} {{- if .exports }} {{- range $key, $value := .exports }} export {{ $key }}={{ .Data.data.$value }} {{- end }} {{- end }} {{- end }}`}}
- 修改后的values.yaml:
vault: enabled: false secrets: - path: path/to/secret/database exports: DB_HOST: host DB_PORT: port - path: path/to/secret/redis exports: REDIS_HOST: host REDIS_PORT: port
遇到的报错
│ vault-agent-init [INFO] (runner) starting │ │ vault-agent-init [ERROR] template.server: template server error: error="(dynamic): parse: template: :5: bad character U+0024 '$'" │ │ vault-agent-init [INFO] (runner) stopping │ │ vault-agent-init [INFO] template.server: template server stopped │ │ vault-agent-init [INFO] auth.handler: shutdown triggered, stopping lifetime watcher │ │ vault-agent-init [INFO] auth.handler: auth handler stopped │ │ vault-agent-init [ERROR] runtime error encountered: error="template server: (dynamic): parse: template: :5: bad character U+0024 '$'" │ │ vault-agent-init Error encountered during run, refer to logs for more details. │ │ Stream closed EOF for service-example/example-generic-internal-xxx-xxx (vault-agent-init)
解决方案
报错原因是Vault Agent模板中使用了错误的map访问语法:{{ .Data.data.$value }}在Go模板里不合法,不能直接用$value作为键名访问map,需要改用index函数来动态获取值。另外还要注意变量作用域问题——嵌套的range循环里$value会被覆盖,需要重命名避免冲突。
正确的Helm模板
{{- range $secret := $.Values.vault.secrets }} {{- $secretName := regexFind "[^/]+$" $secret.path }} # 保留secret注入注解 vault.hashicorp.com/agent-inject-secret-{{ $secretName }}: {{ $secret.path | quote }} # 更新后的模板注解 vault.hashicorp.com/agent-inject-template-{{ $secretName }}: | {{`{{- with secret `}}{{ $secret.path | quote }}{{` -}} # 保留原有JSON输出 {{ .Data.data | toJSON }} {{- if `}}{{ $secret.exports | toJson | ne "{}" }}{{` }} # 生成export环境变量语句 {{- range $envKey, $secretKey := `}}{{ $secret.exports }}{{` }} export {{ $envKey }}={{ index .Data.data $secretKey }} {{- end }} {{- end }} {{- end }}`}} {{- end }}
关键修改点说明
- 变量重命名:将外层循环变量从
$value改为$secret,避免和内层range的$secretKey冲突 - 合法的map访问:用
index .Data.data $secretKey替代错误的{{ .Data.data.$value }},这是Go模板中动态访问map键的标准语法 - exports存在性判断:通过
{{ $secret.exports | toJson | ne "{}" }}判断是否需要生成export语句,避免空exports时输出多余内容 - 保留原有JSON输出:继续保留原来的JSON格式内容,同时追加export语句
最终效果
以database secret为例,生成的/vault/secrets/database内容将变为:
{"host":"example.us-east-1.rds.amazonaws.com","port":5432,"user":"postgres"} export DB_HOST=example.us-east-1.rds.amazonaws.com export DB_PORT=5432
内容的提问来源于stack exchange,提问作者Sachin C
相关产品推荐
相关产品推荐

