在不更改文件结构的情况下更改 yaml 文件中的值

Change value in yaml file without changing the files structure

我正在考虑使用 Jenkins 和 ArgoCD 在我的集群中设置 GitOps CI/CD 管道。

首先,我想为我的 CI 环境创建一个存储库,其中包含我的应用程序的 Helm 图表的一些值文件。

我无法真正弄清楚的一件事是,如何在不更改文件的整个结构的情况下自动编辑 Helm 值文件。

用于读取和写入 yaml 文件的 Jenkins 管道方法将完全重新创建它并在此过程中重新格式化整个文件。

yq 不会(似乎)重新排序键,但它会删除空行和注释,例如。

我唯一想到的是使用 sed。但这感觉有点不对。而且很容易坏掉。就像我在另一个同名组中添加第二个键一样。或者添加或删除键。

这里有一个例子,让它更清楚一点:

我有两个存储库,一个用于我的应用程序,一个用于我的 CI,NI,... 配置。

我的应用程序仓库并不那么重要。只是一些应用程序。我的配置存储库看起来有点像这样:

 .
...
├── ci
│   ├── app1
│   │   ├── Chart.yaml
│   │   ├── values.yaml
│   ├── app2
...
├── staging
│   ├── app1
│   │   ├── Chart.yaml
│   │   ├── values.yaml
│   ├── app2
...

ci 文件夹中 app1values.yaml 文件可能如下所示:

app1:
  image:
    tag: 1.33.7

  ingress:
    enabled: true
    hosts:
      - app1.my-internal-ci.company.com
  ...

实际的 helm 图表在其他地方,这里只是环境中应用程序的配置。

ArgoCD 监视此 repo 并注意所需状态(由 repo 的状态指定)和集群中的实际状态匹配(有关该工具的更多信息,请参阅 https://argoproj.github.io/cd/)。

作为 app1 的 CI 管道的最后一步,它从我的应用程序存储库中的代码构建 docker 图像,应该更新 values.yaml 中的文件配置仓库中的 ci 文件夹,其中包含刚刚构建的应用程序的新版本 1.33.8,并将其作为新提交推送到主分支。

除此之外,还配置了其他值,例如入口,如果需要,我会在 repo 中手动更新这些值。

由于文件由 CI 构建管道自动更新并由开发人员/DevOps 工程师手动更新,我希望能够使它们易于人类阅读(键的顺序,换行符, 评论, ...)

还有其他方法可以实现吗?

提前致谢!

这里可以直接使用helm install -f选项。关于它有两个重要的细节:

  1. 除了图表中的 values.yaml 值外,还使用了 helm install -f 值。您无需在本地设置中重复图表的值。
  2. helm install -f 采用任何有效的 YAML 文件;但是每个有效的 JSON 文件都是一个有效的 YAML 文件,因此如果您的 CI 工具可以写出 JSON,它可以创建一个可以传递给 helm install -f 的文件。

事实上,YAML 文件的精确格式并不重要,只要正确的键、序列和映射具有正确的结构即可。

在 Jenkins 上下文中,您可以使用标准 writeJSON 函数生成本地值文件:

// Only need to provide the specific values we need to set;
// the chart's values.yaml will be used for anything we don't
// directly provide here
helmValues = ['environment': 'production',
              'tag': GIT_COMMIT]
writeJSON file: 'values.deploy.yaml', json: helmValues

sh 'helm upgrade --install -n myproject myproject ./charts/myproject -f values.deploy.yaml'

经过进一步挖掘,我认为我现在拥有的最佳选择是 yq。在较新的版本(> 3.0.0;https://github.com/mikefarah/yq/issues/19)中,它不应再删除任何评论。我想有了 newline-thing 我可以活下去。

因此,如果您有上述文件,您可以更新您的图片标签:

yq -i '.app1.image.tag = "1.33.8"' ci/app1/values.yaml

值得一提:如果您使用的是 kustomize 而不是 Helm,则有一个 built-in:kustomize edit set image my-app=myregistry.io/my-platform/my-app:1.2.3.

感谢您的意见和建议!