【问题标题】:Chef - Different files for different environmentsChef - 不同环境的不同文件
【发布时间】:2015-08-07 08:20:03
【问题描述】:

我是 Chef 的新手,我正在研究为不同环境输出不同文件的环境。例如,我想为暂存或生产环境加载不同的 robots.txt 和 .htaccess 文件。

我从网站上找到了下面的代码,但不确定如何完成我想要做的事情。这可以在 .erb 文件中完成,还是必须在 .rb 文件中完成?

if node.chef_environment == 'development' do
#
# do not configure basic auth
#
else
#
#  configure basic auth
#
end

另外,我如何能够动态更改文件中的内容,而不必创建一个完全独立的文件。例如,我想根据环境更改 js 文件中的链接。这可以通过某处的变量来完成吗?

【问题讨论】:

  • 如果您真的只想更改文件的一小部分,最好使用.erb 文件。正如我在回答中提到的,这可能非常混乱。我认为将您的项目代码(例如 html、js、服务器脚本文件)放入 Chef 本身是一个坏主意;我更喜欢为此使用源代码控制系统(例如 git 或 svn)。
  • 感谢您给予我的所有帮助,感谢您为我指明了正确的方向。
  • 顺便说一句,我使用git进行源代码控制,但需要让js、php等文件的某些部分在创建环境时保持动态
  • 这是一个棘手的情况,我还没有找到 Chef 的顺利解决方案。对于环境中的链接,最好使用相对路径对于在服务之间遍历的链接(例如网站到 API),您需要一个特定于环境的代理服务器(例如具有重写规则的 Apache 或 Nginx)以避免您的源代码被充满了环境感知 .erb 文件。
  • 再次感谢,一切都按预期进行。

标签: chef-infra


【解决方案1】:

可以做任何一种方式,但我会用.rb文件来做。如果您有一个 .htaccess.erb 文件,那么所有不同的环境代码混合在一起会非常拥挤 - 难以阅读/诊断。

我发现有一本专门用于环境设置的食谱会更简洁,让它的食谱检测环境并从食谱中的不同位置获取所有配置文件。您将为此使用cookbook_fileremote_directoryremote_file 资源。

这是来自cookbook_file 资源的一个不错的示例,用于检测平台。您应该能够对其进行调整以检测文件的环境和源位置,而不是目标路径。

cookbook_file "application.pm" do
  path case node['platform']
    when "centos","redhat"
      "/usr/lib/version/1.2.3/dir/application.pm"
    when "arch"
      "/usr/share/version/core_version/dir/application.pm"
    else
      "/etc/version/dir/application.pm"
    end
  source "application-#{node['languages']['perl']['version']}.pm"
  owner "root"
  group "root"
  mode "0644"
end

这样的事情可能对你很有效:

cookbook_file ".htaccess" do
  path "/var/www/"
  source "apache/#{node['chef_environment'].htaccess"
  owner "apache"
  group "apache"
  mode "0400"
end

应该(我生疏了,有一段时间没做厨师了)创建一个名为 .htaccess 的文件,该文件从开发环境中的节点上的 /<cookbook_directory>/files/apache/development.htaccess 复制,并从/<cookbook_directory>/files/apache/production.htaccess 在生产环境的节点上。因此,每个文件都有明确的名称,并且没有任何逻辑 - 不太可能犯任何错误。

【讨论】:

  • 我认为 OP 询问的是不同的环境(Dev、QA、Production)而不是不同的平台(Debian、RHEL)
  • @charlesbabbage 同意了。第一个代码块是链接中的复制/粘贴示例。第二个代码块正在调整它以使用环境而不是平台。
  • 太棒了,非常感谢。至于 robots.txt 文件,这样的东西也可以吗?我不确定我是否也可以从 .rb 文件创建它,因为它是一种不同的文件格式。
  • 当然,您可以以同样的方式获取robots.txt。这种方法的要点是,您要复制的文件是它们自己的格式(.htaccess.txt 都是纯文本),其中没有任何 ruby​​ 代码或模板标记。尽管您可能不需要为不同的环境使用不同的 robots.txt 文件 - 我希望您的非生产环境应该通过不同的方式与爬虫隔离。
【解决方案2】:

您可以使用为您的特定环境配置正确参数的模板和其他文件。例如,这是我创建 /etc/sysconfig/network-scripts/ifcfg-* 文件的模板:

#
# /etc/sysconfig/network-scripts/ifcfg-<%= @interface %>
#
# Generated by Chef for <%= node['hostname'] %>
#
<%= @interface %>
BOOTPROTO=static
ONBOOT=yes
NM_CONTROLLED=no
<%= @hwaddr %>
<%= @ipaddress %>
<%= @netmask %>
<%= @broadcast %>
<%= @master %>
<%= @slave %>

这是我用来填充变量的配方代码。 Recipe 不知道实际值,只知道基础设施设置,即在一个特定环境中有环境并且有不同的子网:

getMac = {}

# Get "physical" interfaces
node['network']['interfaces'].keys.sort.each do |iface|
    if node['network']['interfaces'][iface]['encapsulation'] == 'Ethernet' and
        node['network']['interfaces'][iface]['type'] != 'bond'
        node['network']['interfaces'][iface]['addresses'].keys.each do |address|
            if node['network']['interfaces'][iface]['addresses'][address]['family'] == 'lladdr'
                getMac[iface]=address
            end
        end
    end
end
ip = node['network']['address'][node['hostname']]
env = 'dot' + ip.split('.')[2]
netmask = "NETMASK=" + node['network'][env]['netmask']
broadcast = "BROADCAST=" + node['network'][env]['broadcast']

node['network']['interfaces'].keys.sort.each do |iface|
    if node['network']['interfaces'][iface]['encapsulation'] == 'Ethernet' and 
        node['network']['interfaces'][iface]['type'] != 'bond'
        # find the non-primary interface, which is not one of eth0, em1, or eno1[0-9]*
        # Otherwise, leave IP/netmask/broadcast as assigned above
        if !iface.match(/ens16|eno1|eth0|em1/)
            ipaddress = ''
            netmask = ''
            broadcast = ''
        else
            ipaddress = "IPADDR=" + ip
        end
        template "/etc/sysconfig/network-scripts/ifcfg-#{iface}" do
            source "ifcfg-iface.erb"
            mode 0644
            owner "root"
            group "root"
            variables({
                :interface => "DEVICE=#{iface}",
                :ipaddress => ipaddress, 
                :netmask => netmask,
                :broadcast => broadcast,
                :hwaddr => "HWADDR=#{getMac['iface']}",
            })  
        end 
    end
end

这是环境文件:

override_attributes ({
    'network' => {
        # one environment can use multiple subnets
        'dotX' => {
            'broadcast' => "a.b.X.255",
            'gateway' => "a.b.X.1",
            'netmask' => "255.255.255.0",
        },
        # all nodes for this environment
        'address' => {
            'hostname' => "a.b.X.d",
        },
    },
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    相关资源
    最近更新 更多