我对Chef很新,并且通过尝试使用它来构建Web服务器来进行概念验证。由于这个问题超出范围的原因,我将创建多个我可能想要创建和“删除”的Apache实例。同一个问题可能真的适用于在单个Apache实例中创建和删除虚拟主机配置。
我目前正在使用chef-client根据此节点的已定义属性创建所有Apache实例。例如,我可能有定义Instance1
,Instance2
和Instance3
的属性。在这一点上,这一切都很好。实例目录的创建方式如下:
/opt/local/apache/Instance1/stuff
/opt/local/apache/Instance2/stuff
/opt/local/apache/Instance3/stuff
使用相同的instancename
标识符创建内容目录和服务。
如果我要从此节点的属性中删除Instance3
,则会出现问题。我的厨师 - 客户运行将确保Instance1
& Instance2
已正确配置,但Instance3
将保留为主厨,客户现在对此一无所知。
据我所知,在一个理想的世界中,你可能只是使用新配置启动一台新机器,这个问题甚至没有抬头。但是,我需要在无法重新配置的服务器上执行此操作(这只是在现有服务器上配置Apache的POC)。
我可以“删除并重新创建”,但这对我来说并不是幂等的。首先,文件时间戳会有所不同。即使没有什么可以做,厨师 - 客户做所有这些事情似乎也是错误的。
我自己想出了一个解决方案。在上面的示例中,我将在Ruby中通过globbing /opt/local/apache/
获取所有实例名称的列表,迭代它们并删除实例(如果它不是属性中定义的实例)。我把它放到一个单独的食谱中,我称之为cleanup.rb
。如果我在主安装配方之后运行它并且如果没有删除配置,那么它将什么也不做,所以运行似乎是安全的。
这很好用,但似乎 hacky 我担心这可能是反模式。从概念上讲,我是以正确的方式解决这个问题,还是应该做一些与众不同的事情?在你的食谱中使用自定义Ruby代码来做这样的事情被认为是正常和正确的吗?
答案 0 :(得分:2)
这里的区别通常是(使用Facebook的Phil D中的术语)作为"管理对象"与#34;托管集合"。单个template
资源会聚合地控制文件的状态,但您想要的是一个资源(实际的自定义资源或仅仅是概念上的),它是所有文件的集合。您可以查看zap
cookbook以获得半可重用的实现,但这可以基于挖掘资源集合而不是使用属性。基于属性的收集方法比zap
菜谱更不易碎,但也更有限。 Facebook的方法(即基于属性的)可能最好地体现在他们的sysctl食谱中,https://github.com/facebook/chef-cookbooks/tree/master/cookbooks/fb_sysctl。
在这种情况下,它听起来像做一个dir glob并且针对属性数据进行区分可能是正确的方法,但是只要理解这可能是"棘手的"有时。就像你在配方代码中设置属于那个glob之后的属性一样,它也不会知道它。这通常会导致特殊情况升级,但也许你可以保持更有秩序的事情,这样就可以了:)