Chef - 针对不同环境的不同文件

时间:2014-07-22 14:03:41

标签: chef

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

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

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

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

2 个答案:

答案 0 :(得分:2)

可以以任何方式执行此操作,但我会使用.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复制。因此,每个文件都有明确的名称,没有任何逻辑 - 不太可能犯任何错误。

答案 1 :(得分:0)

您可以使用将配置的模板和具有适合您特定环境的正确参数的其他文件。例如,这是我创建/ 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",
        },
    },
})