You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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正确处理多行字符串:

  1. 先安装yaml解析库:
npm install yaml
# 或
yarn add yaml
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:18:14