首页 > 解决方案 > 从不同的食谱渲染部分模板

问题描述

我们正在多个应用服务器节点上安装电报代理;作为收集服务器指标的监控框架的一部分

这是由 out master cookbook 完成的。

主/食谱/telegraf_install.rb

yum_package 'telegraf' do
  source "#{Chef::Config[:file_cache_path]}/#{node['telegraf']['package']}"
  action :install
end

template '/etc/telegraf/telegraf.conf' do
  source node['telegraf']['template_name']
  owner 'telegraf'
  group 'telegraf'
  mode '0777'
  variables(
    partial_name: node['telegraf']['partial_name'],
    app: node['telegraf']['app'],
    env_name: node['telegraf']['env_name'],

这个主食谱也有默认的配置模板。

主/模板/telegraf_install_default.conf.erb

# Telegraf Configuration.
[global_tags]
  ## Environment variables can be used as tags and throughout the config file (i.e. user = "$USER").
  app = "<%= @app %>"
  env_name = "<%= @env_name %>"
  env_type = "<%= @env_type %>"
  role = "<%= @role %>"

<% unless @partial_name.empty? -%>
 <%= render @partial_name %>
<% end -%>

templates/ 下还有其他模板文件

主/模板/Partial1.conf.erb

# Partial1 service
[[inputs.procstat]]
pattern = "Pattern1"

[inputs.procstat.tags]
service_name = "Service1"
instance = "Instance1"

主/模板/Partial2.conf.erb

[[inputs.proc]]
pattern = "Pattern2"

[inputs.proc.tags]
service_name = "Service2"
instance = "Instance2"

一直以来,我们都是在 master cookbook 下编写角色文件

主/角色/Application1_DEV.json

"default_attributes": {
            "telegraf": {
                "template_name": "telegraf_install_default.conf.erb",
                "app": "App1",
                "env_name": "DEV1",
                "env_type": "DEV",

主/角色/Application1_UAT.json

"default_attributes": {
            "telegraf": {
                "template_name": "telegraf_install_default.conf.erb",
                "partial_name": "Partial1.conf.erb",
                "app": "App1",
                "env_name": "UAT1",
                "env_type": "UAT",

主/角色/Application2_DEV.json

"default_attributes": {
            "telegraf": {
                "template_name": "telegraf_install_default.conf.erb",
                "partial_name": "Partial2.conf.erb",
                "app": "App2",
                "env_name": "DEV1",
                "env_type": "DEV",

注意:并非所有应用程序都需要部分模板;仅当某些应用程序需要一些自定义或特定要求时才需要部分模板,否则呈现默认模板

然而,随着时间的推移,许多应用程序都被用于多种环境。角色文件的数量越来越多,难以跟踪和维护。

然后我们计划为每个单独的应用程序创建包装说明书,这样

所以现在我们有了这样的包装食谱:-

wrapper1/模板/Partial1.erb

wrapper1/role/Application1_DEV.json

wrapper1/role/Application1_UAT.json

wrapper2/模板/Partial2.erb

wrapper2/role/Application2_DEV.json

根据要求;我们希望将基本食谱与所有包装器隔离开来;因此我们想从包装食谱中传递部分模板文件(它们是特定于应用程序的)。

我们通过将渲染逻辑更改为此来做到这一点;

<%= render @partial_name , :cookbook => 'wrapper1' %>
Chef::Mixin::Template::TemplateError (Cookbook wrapper1 not found. If you're loading wrapper1 from another cookbook, make sure you configure the dependency in your metadata) on line #20:

 18:
 19: <% unless @partial_name.empty? -%>
 20:  <%= render @partial_name, :cookbook => 'wrapper1' %>
 21: <% end -%>
 22:

当我在主食谱中添加包装器的依赖项时;错误消失了,我们成功收敛

然而,这违背了隔离主说明书的目的,对于包装说明书中的每个部分模板,我需要在主说明书元数据中添加包装器依赖项。

我希望我能够解释我的要求。感谢您是否可以建议是否有任何解决方法,或者可能有其他方法来解决这个问题。

标签: chef-infra

解决方案


在主食谱中创建一个自定义资源,然后在依赖于主食谱的任何食谱中使用它


推荐阅读