将一个条件应用于一组 Chef 资源的更简单方法

将一个条件应用于一组 Chef 资源的更简单方法

在 Chef 食谱的这一部分中,有 4 个execute资源。它们应该仅在文件不存在时运行。这作为条件添加到第一个资源中,然后触发整个链的运行。

# Set up default SSL cert
execute "defaultcert1" do
    not_if {File.exist?("/vol/webserver/cert")}
    command "mkdir /vol/webserver/cert"
    notifies :run, "execute[defaultcert2]", :immediately
end
execute "defaultcert2" do
    action :nothing
    command "ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem /vol/webserver/cert/server.crt"
    notifies :run, "execute[defaultcert3]", :immediately
end
execute "defaultcert3" do
    action :nothing
    command "ln -s /etc/ssl/private/ssl-cert-snakeoil.key /vol/webserver/cert/server.key"
    notifies :run, "execute[defaultcert4]", :immediately
end
execute "defaultcert4" do
    action :nothing
    command "chown -R ubuntu:ubuntu /vol/webserver/cert"
end

如您所见,保护 4 条命令的代码量相当大。有没有更好的方法来实现这一点?

答案1

对于你的特定示例,我建议使用 Chef 的directorylink资源,而不是花费:

directory "/vol/webserver/cert" do
    user "ubuntu"
    group "ubuntu"
end

link "/vol/webserver/cert/server.crt" do
    to "/etc/ssl/certs/ssl-cert-snakeoil.pem"
end
link "/vol/webserver/cert/server.key" do
    to "/etc/ssl/certs/ssl-cert-snakeoil.key"
end

您不需要用not_if's 和通知来保护这些 - 如果目录和链接已经具有正确的属性,Chef 将不会执行任何事情。

另一方面,假设您想使用 snakeoil 证书和密钥(如果一开始什么都没有),但如果文件已经存在,则不执行任何操作。在这种情况下,我会not_if在链接资源上使用:

directory "/vol/webserver/cert" do
    user "ubuntu"
    group "ubuntu"
end

link "/vol/webserver/cert/server.crt" do
    to "/etc/ssl/certs/ssl-cert-snakeoil.pem"
    not_if "test -e /vol/webserver/cert/server.crt"
end

link "/vol/webserver/cert/server.key" do
    to "/etc/ssl/certs/ssl-cert-snakeoil.key"
    not_if "test -e /vol/webserver/cert/server.key"
end

与资源字符串相比execute,这更清楚地传达了意图 - 它表示目录需要存在(具有正确的用户和组),并且除非已经存在某些内容,否则应该创建几个符号链接。

最后,如果你确实有几个相关的 shell 命令需要一起执行,可以考虑使用script资源。

相关内容