如何让CDKTF保留Helm values文件中的多行字符串格式?
问题:CDKTF部署Helm Chart时丢失Values文件中的多行字符串格式
问题场景
原始Helm Values文件
role: agent customConfig: data_dir: /vector-data-dir api: enabled: false sources: graph-node-logs: type: kubernetes_logs extra_label_selector: "graph-node-indexer=true" transforms: parse_graph_node_logs: inputs: - graph-node-logs type: remap source: > # Extract timestamp, severity and message # we ignore the timestamp as explained below regexed = parse_regex!(.message, r'^(?P<timestamp>\w\w\w \d\d \d\d:\d\d:\d\d\.\d\d\d) (?P<severity>[A-Z]+) (?P<message>.*)$') # From the message, extract the subgraph id (the ipfs hash) message_parts = split(regexed.message, ", ", 2) structured = parse_key_value(message_parts[1], key_value_delimiter: ":", field_delimiter: ",") ?? {} # construct the final fields we care about which are the subgraph id, the severity, the message and the unix timestamp final_fields = {} final_fields.subgraph_id = structured.subgraph_id final_fields.message = regexed.message final_fields.severity = regexed.severity # graph node does not emit time zone information and thus we can't use the timestamp we extract # because we can't coerce the extracted timestamp into an umabiguous timestamp. Therefore, # we use the timestamp of the log event instead as seen by the source plugin (docker-logs) final_fields.unix_timestamp = to_unix_timestamp!(.timestamp || now(), unit: "milliseconds") # Add the final fields to the root object. The clickhouse integration below will discard fields unknown to the schema. . |= final_fields sinks: stdout: type: console encoding: codec: json target: stdout inputs: - parse_graph_node_logs service: enabled: false
CDKTF使用代码
const valuesAsset = new TerraformAsset(this, "vector-values", { path: `./${EnvConfig.name}-values.yaml`, type: AssetType.FILE, }); new helm.Release(this, "vector", { repository: "https://helm.vector.dev", chart: "vector", name: "vector", version: "0.21.1", values: [Fn.file(valuesAsset.path)], });
问题现象
生成的ConfigMap中,transforms.parse_graph_node_logs.source的多行内容被合并,注释和代码挤在同一行:
apiVersion: v1 data: vector.yaml: | api: enabled: false data_dir: /vector-data-dir sinks: stdout: encoding: codec: json inputs: - parse_graph_node_logs target: stdout type: console sources: graph-node-logs: extra_label_selector: graph-node-indexer=true type: kubernetes_logs transforms: parse_graph_node_logs: inputs: - graph-node-logs source: | # Extract timestamp, severity and message # we ignore the timestamp as explained below regexed = parse_regex!(.message, r'^(?P<timestamp>\w\w\w \d\d \d\d:\d\d:\d\d\.\d\d\d) (?P<severity>[A-Z]+) (?P<message>.*)$') # From the message, extract the subgraph id (the ipfs hash) message_parts = split(regexed.message, ", ", 2) structured = parse_key_value(message_parts[1], key_value_delimiter: ":", field_delimiter: ",") ?? {} # construct the final fields we care about which are the subgraph id, the severity, the message and the unix timestamp final_fields = {} final_fields.subgraph_id = structured.subgraph_id final_fields.message = regexed.message final_fields.severity = regexed.severity # graph node does not emit time zone information and thus we can't use the timestamp we extract # because we can't coerce the extracted timestamp into an umabiguous timestamp. Therefore, # we use the timestamp of the log event instead as seen by the source plugin (docker-logs) final_fields.unix_timestamp = to_unix_timestamp!(.timestamp || now(), unit: "milliseconds") # Add the final fields to the root object. The clickhouse integration below will discard fields unknown to the schema. . |= final_fields type: remap kind: ConfigMap # 省略元数据部分
解决方案
方法1:修改YAML多行字符串语法
YAML中>是折叠块标量,会自动将换行转换为空格;而|是保留块标量,会完整保留换行符。把Values文件中source: >改为source: |即可:
transforms: parse_graph_node_logs: inputs: - graph-node-logs type: remap source: | # 替换>为| # Extract timestamp, severity and message # we ignore the timestamp as explained below regexed = parse_regex!(.message, r'^(?P<timestamp>\w\w\w \d\d \d\d:\d\d:\d\d\.\d\d\d) (?P<severity>[A-Z]+) (?P<message>.*)$') # 后续内容保持不变
方法2:在CDKTF中解析YAML为对象后传入
避免使用Fn.file直接读取字符串,而是将YAML文件解析为TypeScript对象,再传给Helm Release的values参数,确保CDKTF正确处理多行字符串:
- 先安装yaml解析库:
npm install yaml # 或 yarn add yaml
- 修改CDKTF代码:
import * as fs from 'fs'; import * as YAML from 'yaml'; // 读取并解析YAML文件 const valuesContent = fs.readFileSync(`./${EnvConfig.name}-values.yaml`, 'utf8'); const values = YAML.parse(valuesContent); new helm.Release(this, "vector", { repository: "https://helm.vector.dev", chart: "vector", name: "vector", version: "0.21.1", values: [values], // 传入解析后的对象 });
验证结果
修改后,生成的ConfigMap中source字段会完整保留原始的多行格式,注释和代码各行独立,符合预期。
内容的提问来源于stack exchange,提问作者Paymahn Moghadasian
相关产品推荐
相关产品推荐

