### 创建 Facter 的自定义 fact
虽然 Facter 内置的 facts 很有用,但实际上添加你自己的 facts 也是很容易的。 例如,如果你的机器位于不同的数据中心或托管提供商,你可以为此目的添加一个 **自定义 fact** 以便让 Puppet 决定是否需要应用一些本地设置(例如,本地 DNS 服务器)。
#### 准备工作
1. 在配置文件 puppet.conf 中开启 pluginsync 选项:
```
[main]
pluginsync = true
```
2. 为 fact 创建一个目录。此目录位于相应的模块目录中,目录名为 lib/facter。 例如,你可以使用目录 modules/admin/lib/facter。你创建的任何自定义 facts 都位于此目录下并且 Puppet 会将其同步到客户端。
#### 操作步骤
1. 创建一个名为 hello.rb 的包含如下内容的脚本文件:
```
Facter.add(:hello) do
setcode do
"Hello, world"
end
end
```
2. 在客户端运行 Puppet。这会将 fact 同步到客户机:
```
# puppet agent --test
info: Retrieving plugin
notice: /File[/var/lib/puppet/lib/facter/hello.rb]/ensure: defined
content as '{md5}7314e71d35db83b563a253e741121b1d'
info: Loading downloaded plugin /var/lib/puppet/lib/facter/hello.rb
info: Loading facts in hello
info: Loading facts in hello
info: Loading facts in hello
info: Loading facts in hello
info: Connecting to sqlite3 database: /var/lib/puppet/state/
clientconfigs.sqlite3
info: Caching catalog for cookbook.bitfieldconsulting.com
info: Applying configuration version '1297258039'
notice: Finished catalog run in 0.57 seconds
```
3. 通过直接运行 Facter 命令的方式检测 fact:
```
# facter hello
Hello, world
```
4. 现在你可以在一个 Puppet 的配置清单中应用这个自定义的 fact:
```
notify { $hello: }
```
5. 当你运行 Puppet,对自定义 fact 的引用将返回其对应的值:
```
notice: Hello, world
```
#### 工作原理
Facter 内置的 facts 与我们刚刚创建的自定义 fact 相同的方式定义。 这种架构使添加和修改 facts 更为方便,并为你提供了一种在配置清单中读取主机信息的标准方法。
Facts 可以包含任何 Ruby 代码,语句块 setcode do … end 中最后算出的值将作为 fact 的返回值。 例如,你可以做个更有用的 fact,下面的代码将返回当前登录的用户数:
```
Facter.add(:users) do
setcode do
%x{/usr/bin/who |wc -l}.chomp
end
end
```
其输出是:
```
notice: 2 users logged in
```
#### 更多用法
你可以扩展 facts 使用以创建一个完全 “无节点定义(nodeless)” 的 Puppet 配置: 换言之,Puppet 可以仅基于 facts 的结果决定将哪些资源应用到一台机器。 Jordan Sissel 写了篇介绍这种方法的文章: [http://www.semicomplete.com/blog/geekery/puppet-nodeless-configuration.html](http://www.semicomplete.com/blog/geekery/puppet-nodeless-configuration.html) 。
在网络上有许多可用的自定义 facts 的例子,包括 Cosimo Streppone 撰写的关于 “根据 IP 地址决定数据中心的位置” 的文章,网址为: [http://my.opera.com/cstrep/blog/puppet-custom-facts-and-master-less-puppet-deployment](http://my.opera.com/cstrep/blog/puppet-custom-facts-and-master-less-puppet-deployment) 。
- Puppet 2.7 Cookbook 中文版
- 中文翻译版
- 译者序
- 项目缘起
- 翻译方法
- 社区链接
- 社区建议
- 贡献者
- 原书版权页
- 关于作者
- 前言
- 本书内容
- 阅读前提
- 适用读者
- 格式约定
- 读者反馈
- 客户支持
- 下载案例代码
- 勘误表
- Puppet 基础设施
- 使用版本控制
- 使用提交钩子
- 使用 Rake 部署变更
- 配置 Puppet 的文件服务器
- 从 cron 运行 Puppet
- 使用自动签名
- 预签名证书
- 从 Puppet 的 filebucket 检索文件
- 使用 Passenger 扩展 Puppet 的部署规模
- 创建去中心化的分布式 Puppet 架构
- 监控、报告和排错
- 生成报告
- 通过 Email 发送包含特定标签的日志信息
- 创建图形化报告
- 自动生成 HTML 文档
- 绘制依赖关系图
- 测试你的 Puppet 配置清单
- 执行模拟运行
- 检测编译错误
- 理解 Puppet 的错误信息
- 显示命令的输出结果
- 输出调试信息
- 检查配置设置
- 使用标签
- 使用运行阶段
- 使用不同的环境
- Puppet 语言及其写作风格
- 使用 Puppet 社区规范
- 使用模块
- 使用标准的命名规范
- 使用嵌入式 Ruby 代码
- 使用纯 Ruby 代码书写配置清单
- 遍历多个项目
- 书写强大的条件语句
- 在 if 语句中使用正则表达式
- 使用选择器和 case 语句
- 检测字符串中是否包含指定的值
- 使用正则表达式替换
- 书写更优质的配置清单
- 使用资源的数组
- 使用 define 资源
- 指定资源的依赖关系
- 使用节点继承
- 使用类的继承和重载
- 给类传递参数
- 书写可重用的跨平台配置清单
- 获得系统的环境信息
- 导入动态信息
- 从 CSV 文件导入数据
- 给 Shell 命令传递参数
- 使用文件和软件包
- 为配置文件添加配置行
- 使用 Augeas 自动修改配置文件
- 使用配置片段构建配置文件
- 使用 ERB 模板
- 在模板中遍历数组
- 从第三方仓库安装软件包
- 配置 APT 软件仓库
- 配置 GEM 仓库
- 从源码包自动构建软件
- 比较软件包的版本
- 用户和虚拟资源
- 使用虚拟资源
- 使用虚拟资源管理用户
- 管理用户基于密钥的 SSH 访问
- 管理用户的自定义文件
- 有效地分发 cron 任务
- 当文件更新时运行命令
- 使用主机资源
- 为文件资源指定多个源
- 使用文件资源递归地分发整个目录树
- 清理过期的旧文件
- 使用日程表资源
- 资源的审计
- 临时禁用资源
- 管理时区
- 应用程序
- 管理 Apache 服务
- 创建 Apache 虚拟主机
- 创建 Nginx 虚拟主机
- 创建 MySQL 数据库及用户
- 管理 Drupal 站点
- 管理 Rails 应用程序
- 服务器和云基础设施
- 部署 Nagios 监控服务器
- 使用 Heartbeat 构建高可用服务
- 管理 NFS 服务和文件共享
- 使用 HAProxy 为多个 web 服务器实现负载均衡
- 使用 iptables 管理防火墙
- 管理 Amazon 的 EC2 实例
- 使用 Vagrant 管理虚拟机
- 外部工具和 Puppet 生态环境
- 创建 Facter 的自定义 fact
- 在运行 Puppet 之前和之后执行命令
- 从 Shell 会话生成 Puppet 配置清单
- 从运行的系统上生成 Puppet 配置清单
- 使用 Puppet Dashboard
- 使用 Foreman
- 使用 MCollective
- 使用公共模块
- 使用外部节点分类器
- 创建自定义的资源类型
- 创建自定义的提供者