在不更改文件结构的情况下更改 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
文件夹中 app1
的 values.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
选项。关于它有两个重要的细节:
- 除了图表中的
values.yaml
值外,还使用了 helm install -f
值。您无需在本地设置中重复图表的值。
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
.
感谢您的意见和建议!
我正在考虑使用 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
文件夹中 app1
的 values.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
选项。关于它有两个重要的细节:
- 除了图表中的
values.yaml
值外,还使用了helm install -f
值。您无需在本地设置中重复图表的值。 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
.
感谢您的意见和建议!