你如何模块化厨师食谱?

时间:2013-05-07 17:27:57

标签: ruby chef chef-recipe cookbook

这是一个工作方法的示例,它循环遍历一系列网站名称,并使用createIisWebsite()函数在IIS中创建它们。

def createIisWebsite(websiteName)
    iis_site websiteName do
    protocol :http
    port 80
    path "#{node['iis']['docroot']}/#{websiteName}"
    host_header  "#{websiteName}.test.kermit.a-aws.co.uk"
    action [:add,:start]
    end
end
在我们的实际解决方案中,此数据存储在其他位置并通过Web API访问。
websiteNames = ["website-2", "website-3", "website-4"]

for websiteName in websiteNames do
    createIisWebsite websiteName
end

现在我希望能够从本Cookbook中的多个食谱中调用createIisWebsite()函数。

我已经尝试将它扔进帮助模块(库)。在那里,我无法获得对iis_site的引用。

我尝试将函数移动到default.rb,然后执行include_recipe“:: default”。这似乎也不起作用。

我收到“在Windows版本6.2.9200上找不到createIisWebsite的资源”

我采用这种方法的原因是因为我希望有一个包含每个Web服务器集群的网站列表的配方。我觉得我没有采取最佳练习路线。

有什么想法吗?

1 个答案:

答案 0 :(得分:5)

问题是该功能正在配方中定义,并且只能在该配方中使用。 include_recipe方法确保加载给定的配方,但它不会将任何内容导入到包含的配方中。

由于您的函数用于声明具有一些计算参数的Chef资源,因此最接近的是Definition (Chef Docs)。定义与Resources类似,具有名称和一组可选参数,但实际上是简单的宏,在编译时会扩展到配方中。

在您的食谱目录中,创建包含以下内容的definitions/my_iis_website.rb

define :my_iis_website do
    iis_site websiteName do
        protocol :http
        port 80
        path "#{node['iis']['docroot']}/#{websiteName}"
        host_header  "#{websiteName}.test.kermit.a-aws.co.uk"
        action [:add,:start]
    end
end

然后,用以下代码替换食谱中的循环:

for websiteName in websiteNames do
    my_iis_website websiteName
end

如果您对每个服务器群集的配方相同但对于网站列表,您可能需要考虑将这些数据存储在attributesdata bags中。这有助于您避免在食谱中重复自己,并且还允许您在不更新食谱的情况下添加网站。