你如何模块化厨师食谱?

时间:2022-11-15 00:22:57

Here is an example of a working recipe that loops through an array of website names and creates them in IIS using the function createIisWebsite().

下面是一个工作配方示例,它循环遍历一系列网站名称,并使用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
In our actual solution this data is stored elsewhere and accessed via a web API.
websiteNames = ["website-2", "website-3", "website-4"]

for websiteName in websiteNames do
    createIisWebsite websiteName
end

Now I want to be able to call the function createIisWebsite() from multiple recipes within this Cookbook.

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

I have tried throwing it into a helper module (library). There I cannot get the reference to iis_site to work.

我试过把它扔进一个帮助模块(库)。在那里,我无法获得对iis_site的引用。

I have tried moving the function to default.rb and then doing include_recipe "::default". That does not seem to work either.

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

I get a "Cannot find a resource for createIisWebsite on windows version 6.2.9200"

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

The reason I am taking this approach is because I want to have a recipe containing the list of websites per cluster of web servers. I get the feeling I am not taking the best practice route.

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

Any ideas?

1 个解决方案

#1


5  

The problem is that the function is being defined inside a recipe, and can only be used within that recipe. The include_recipe method ensures that a given recipe is loaded, but it doesn't import anything into the recipe doing the including.

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

Since your function is being used to declare a Chef resource with some calculated parameters, the closest thing to look at is the Definition (Chef Docs). Definitions look similar to Resources, having a name and a set of optional parameters, but are actually simple macros that are expanded into the recipe when it is compiled.

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

In your cookbook directory, create definitions/my_iis_website.rb containing something like:

在cookbook目录中,创建包含以下内容的定义/ 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

Then, replace the loop in your recipe with:

然后,用以下代码替换配方中的循环:

for websiteName in websiteNames do
    my_iis_website websiteName
end

If your recipes for each cluster of server would be identical but for the list of sites, you might want to consider storing this data in attributes or data bags instead. This helps you to avoid repeating yourself in your recipes, and will also allow you to add sites without updating your cookbook.

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

#1


5  

The problem is that the function is being defined inside a recipe, and can only be used within that recipe. The include_recipe method ensures that a given recipe is loaded, but it doesn't import anything into the recipe doing the including.

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

Since your function is being used to declare a Chef resource with some calculated parameters, the closest thing to look at is the Definition (Chef Docs). Definitions look similar to Resources, having a name and a set of optional parameters, but are actually simple macros that are expanded into the recipe when it is compiled.

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

In your cookbook directory, create definitions/my_iis_website.rb containing something like:

在cookbook目录中,创建包含以下内容的定义/ 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

Then, replace the loop in your recipe with:

然后,用以下代码替换配方中的循环:

for websiteName in websiteNames do
    my_iis_website websiteName
end

If your recipes for each cluster of server would be identical but for the list of sites, you might want to consider storing this data in attributes or data bags instead. This helps you to avoid repeating yourself in your recipes, and will also allow you to add sites without updating your cookbook.

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