### 指定資源的依賴關系
> Remove wrapper, open mouth, insert muffin, eat.
>
> — Instructions on 7-11 muffin packaging
為確保事物以正確的順序發生,你可以在 Puppet 中指定一個資源依賴另一個資源, 例如:你必須先安裝軟件包 X 然后再啟動它提供的服務,因此應該標記這項服務依賴于軟件包 X。 Puppet 會按要求的順序排出它遇到的所有依賴。
在一些配置管理系統中,資源按照你的書寫順序被應用,換句話說,資源被應用的順序是隱式的。 Puppet 則不是這種情況,資源或多或少以一種隨機(但一致)順序被應用, 除非你明確地使用依賴關系指出應用的順序。 一些人更喜歡隱式的方式,因為你可以按照你需要的執行順序書寫資源定義, 并且這就是它們被執行的方式。
另一方面,許多情況下資源的順序無關緊要。使用隱式風格的系統時, 你不能明確地告訴系統,資源 B 是否被寫在了資源 A 之后,由于資源 B 依賴于 A; 或者說書寫的順序是否正確,即資源 A 寫在了資源 B 之前。 這使得重構更加困難,因為移動資源有可能會打破一些隱式的依賴關系。
雖然 Puppet 會讓你多做一點兒工作,就是預先指定依賴關系, 但是這樣產生的代碼會更清晰且更易于維護。讓我們看一個例子。
#### 操作步驟
1. 使用如下的內容創建一個新文件 /etc/puppet/modules/admin/manifests/ntp.pp:
```
class admin::ntp {
package { "ntp":
ensure => installed,
}
service { "ntp":
ensure => running,
require => Package["ntp"],
}
file { "/etc/ntp.conf":
source => "puppet:///modules/admin/ntp.conf",
notify => Service["ntp"],
require => Package["ntp"],
}
}
```
2. 復制已經存在的 ntp.conf 文件到 Puppet 的如下目錄:
```
# cp /etc/ntp.conf /etc/puppet/modules/admin/files
```
3. 在 nodes.pp 中將 admin::ntp 類添加到你的服務器:
```
node cookbook {
include admin::ntp
}
```
4. 現在刪除系統中已存在的 ntp.conf 文件:
```
# rm /etc/ntp.conf
```
5. 運行 Puppet:
```
# puppet agent --test
info: Retrieving plugin
info: Caching catalog for cookbook.bitfieldconsulting.com
info: Applying configuration version '1302960655'
notice: /Stage[main]/Admin::Ntp/File[/etc/ntp.conf]/ensure:
defined content as '{md5}3386aaad98dd5e0b28428966dac9e1f5'
info: /Stage[main]/Admin::Ntp/File[/etc/ntp.conf]: Scheduling
refresh of Service[ntp]
notice: /Stage[main]/Admin::Ntp/Service[ntp]: Triggered 'refresh'
from 1 events
notice: Finished catalog run in 2.36 seconds
```
#### 工作原理
在本例中演示了兩種類型的依賴: require 和 notify。在第一種情況中, ntp 服務要求 ntp 包資源首先被應用:
```
service { "ntp":
ensure => running,
require => Package["ntp"],
}
```
在第二種情況中,NTP 的配置文件設置成了 notify(通知)ntp 服務;換句話說, 一旦發現配置文件有變化,Puppet 就應該使用新的配置文件重新啟動 ntp 服務:
```
file { "/etc/ntp.conf":
source => "puppet:///modules/admin/ntp.conf",
notify => Service["ntp"],
require => Package["ntp"],
}
```
這意味著服務依賴于配置文件以及所安裝的軟件包,Puppet 會按照如下的正確順序來應用這三個資源:
```
Package["ntp"] -> File["/etc/ntp.conf"] ~> Service["ntp"]
```
事實上,這是指定相同依賴關系鏈的另一種方法。添加上面這行到你的配置清單中, 就會產生和上例中使用 require 和 notify 參數的同樣效果 (-> 表示 require,~> 表示 notify)。然而,我更喜歡使用 require 和 notify, 因為依賴關系被定義成了資源的一部分,因此更容易看清將會發生什么。 不過,對于復雜的依賴關系鏈,你可能想使用 -> 符號來代替。
#### 更多用法
你也可以指定一個資源依賴于某個類:
```
require => Class["my-apt-repo"]
```
你不僅可以指定資源和類之間的依賴關系,甚至可以指定 **collections** 之間的依賴關系:
```
Yumrepo <| |> -> Package <| provider == yum |>
```
這是一種功能強大的表達方式,所有 provider 是 yum 的 package 資源被應用之前, 所有的 yumrepo 資源首先都應該被應用。
>  歷史說明:
> 在 Puppet 2.7 版本之前, 所有資源編目都以非確定性的方式被應用, 這意味著每次 Puppet 運行資源的順序都會不同。這可能會導致一些有趣的問題, 比如一個 Puppet 配置清單在一臺機器上能運行成功而在另一臺機器上卻運行失敗。 經過 Puppet Labs 的努力,現在這種情況已經不會發生。現在 Puppet 既保證可靠成功,又保證可靠失敗("either succeed reliably, or fail reliably")。 如果你還在使用早期版本并且遇到了這種問題,請更新到新版本。
- 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
- 使用公共模塊
- 使用外部節點分類器
- 創建自定義的資源類型
- 創建自定義的提供者