我正在使用puppet从facter中读取事实,并在此基础上对我的模块应用不同的配置。
问题:
傀儡特工没有看到这个事实。以交互方式运行puppet agent --test
可以正常工作。即使是从脚本中以非交互方式运行它似乎也很好。只有特工自己搞砸了。
流程:
我正在EC2上部署一个基于Ubuntu的应用程序堆栈。使用userdata(#cloud-config),我在/etc/environment:中设置了一个环境变量
export FACTER_tl_role=development
然后立即在#cloud-config中,i source/etc/environment。只有到那时,我才能安装puppet(我不再使用package:ppuppet来消除#cloud-config步骤序列中的歧义)
一旦实例启动,我确认事实是可用的:运行facter tl_role
返回"0";开发";。然后我检查/var/log/syslog,很明显傀儡代理没有看到这个事实——我知道这一点是因为它无法编译目录,而且根据这个事实,我应该看到的变量集的值没有任何内容(空白)。
但是,运行puppet agent --test
可以以交互方式编译和运行目录。即使是从#cloud-config脚本(在安装puppet之后立即运行)运行这个也很好。
我该如何向傀儡特工提供这一事实?重新启动代理服务没有什么区别,它仍然不知道自定义事实。重新启动实例也没有什么区别。
这是一些代码:
EC2用户数据:
#cloud-config
puppet:
conf:
agent:
server: "puppet.foo.bar"
certname: "%i.%f"
report: "true"
runcmd:
- sleep 20
- echo 'export FACTER_tl_role=development' >> /etc/environment
- . /etc/environment
- apt-get install puppet
- puppet agent --test
主要木偶清单:
# /etc/puppet/manifests/site.pp
node default {
case $tl_role {
'development': { $sitedomain = "dev.foo.bar"}
'production': { $sitedomain = "new.foo.bar"}
}
class {"code" : sitedomain => $sitedomain}
class {"apache::site" : sitedomain => $sitedomain}
class {"nodejs::grunt-daemon" : sitedomain => $sitedomain}
然后我在$sitedomain应该在的地方看到了故障,所以$tl_role似乎没有设置。
有什么想法吗?这让我的大脑爆炸了。。。。
另一个简单的选择是将一个事实放入外部事实中。
将文件拖放到/etc/facter/facts.d/*中相当容易,您可以使用文本文件、yaml-json或可执行文件来完成此操作
http://docs.puppetlabs.com/guides/custom_facts.html#external-事实
*这是在开源木偶上,在unix-y机器上。请参阅完整文档的链接。
谢谢你,@christopher。这可能是一个很好的解决方案,我会测试它,并可能从我目前可怕的黑客攻击中转移到它。我在Puppet用户谷歌小组中得到的答案是,我不应该假设Puppet代理进程将有一个登录外壳的环境,并且当它由Puppet agent运行时,Facter也将有这个环境。
以下是我解决问题的方法(无可否认,是用蛮力):
runcmd:
- echo 'export FACTER_tl_role=development' >> /etc/environment
- . /etc/environment
- apt-get install puppet
- service puppet stop
- sed -i '/init-functions/a. /etc/environment' /etc/init.d/puppet
- puppet agent --test
- service puppet start
正如您所看到的,在安装Puppet之后,我停止了代理,并在/etc/init.d/Puppet到source/etc/environment中添加了一行。然后我启动代理。不理想。。。但它有效!
我认为. /etc/environment
不会像云初始化执行runcmd
那样正常工作。两种可能的解决方案:
-
使用伪代理命令导出变量:
export FACTER_tl_role=development && puppet agent --test
如果不起作用:
- 只需将命令放入用户数据脚本中,并将它们连接在一起作为"多部分输入"(在cloudinit-docs中描述)
第二个解决方案将命令作为一个合适的shell脚本来执行,很可能会解决问题。不过,如果第一种方法有效,那么就更容易处理你所拥有的。