### 管理 Rails 應用程序
**Rails** 是一個非常受歡迎的 Web 應用程序框架(從某種意義上說,是由于它被廣泛應用而不是人們真正喜歡它)。 因此,在某些時候,你可能會被要求管理它。 本節要介紹的處方包含了安裝一臺運行 Rails 應用程序服務器所要做的絕大部分工作。 本處方假定你會使用 Nginx 和 **Passenger** 作為 Web 服務器, 然而你也可以輕松地修改本處方,使用 Apache 替換它。
#### 操作步驟
1. 創建 rails 模塊的目錄結構:
```
# mkdir /etc/puppet/modules/rails
# mkdir /etc/puppet/modules/rails/manifests
# mkdir /etc/puppet/modules/rails/templates
# mkdir /etc/puppet/modules/rails/files
```
2. 使用如下內容創建 /etc/puppet/modules/rails/manifests/init.pp 文件:
```
class rails {
include rails::passenger
package { "bundler":
provider => gem,
ensure => installed,
}
define app( $sitedomain ) {
include rails
file { "/opt/nginx/sites-available/${name}.conf":
content => template("rails/app.conf.erb"),
require => File["/opt/nginx/sites-available"],
}
file { "/opt/nginx/sites-enabled/${name}.conf":
ensure => link,
target => "/opt/nginx/sites-available/${name}.conf",
require => File["/opt/nginx/sites-enabled"],
notify => Exec["reload-nginx"],
}
file { "/opt/nginx/conf/includes/${name}.conf":
source => [ "puppet:///modules/rails/${name}.conf",
"puppet:///modules/rails/empty.conf" ],
notify => Exec["reload-nginx"],
}
file { [ "/var/www",
"/var/www/${name}",
"/var/www/${name}/releases",
"/var/www/${name}/shared",
"/var/www/${name}/shared/config",
"/var/www/${name}/shared/log",
"/var/www/${name}/shared/system" ]:
ensure => directory,
mode => 775,
owner => "www-data",
group => "www-data",
}
}
}
```
3. 使用如下內容創建 /etc/puppet/modules/rails/manifests/passenger.pp 文件:
```
class rails::passenger {
$passenger_version = "3.0.7"
$passenger_dependencies = [ "build-essential",
"libcurl4-openssl-dev",
"libssl-dev",
"ruby",
"rubygems" ]
package { $passenger_dependencies: ensure => installed }
exec { "install-passenger":
command => "/usr/bin/gem install passenger
--version=${passenger_version}",
unless => "/usr/bin/gem list | /bin/grep passenger |/bin/
grep ${passenger_version}",
require => [ Package["rubygems"], Package[$passenger_
dependencies] ],
timeout => "-1",
}
exec { "install-passenger-nginx-module":
command => "/usr/lib/ruby/gems/1.8/gems/passenger-
${passenger_version}/bin/passenger-install-nginx-module
--auto --auto-download --prefix=/opt/nginx",
creates => "/opt/nginx/sbin/nginx",
require => Exec["install-passenger"],
timeout => "-1",
}
file { [ "/opt/nginx",
"/opt/nginx/conf",
"/opt/nginx/conf/includes",
"/opt/nginx/sites-enabled",
"/opt/nginx/sites-available",
"/var/log/nginx" ]:
ensure => directory,
owner => "www-data",
group => "www-data",
}
file { "/opt/nginx/sites-enabled/default":
ensure => absent,
require => Exec["install-passenger-nginx-module"],
}
file { "/opt/nginx/conf/nginx.conf":
content => template("rails/nginx.conf.erb"),
notify => Exec["reload-nginx"],
require => Exec["install-passenger-nginx-module"],
}
file { "/etc/init.d/nginx":
source => "puppet:///modules/rails/nginx.init",
mode => "700",
require => Exec["install-passenger-nginx-module"],
}
service { "nginx":
enable => true,
ensure => running,
require => File["/etc/init.d/nginx"],
}
exec { "reload-nginx":
command => "/opt/nginx/sbin/nginx -t && /etc/init.d/nginx reload",
refreshonly => true,
require => Exec["install-passenger-nginx-module"],
}
}
```
4. 使用如下內容創建 /etc/puppet/modules/rails/templates/app.conf.erb 文件:
```
server {
listen 80;
root /var/www/<%= name %>/current/public;
server_name <%= sitedomain %>;
access_log /var/log/nginx/<%= name %>.access.log;
error_log /var/log/nginx/<%= name %>.error.log;
passenger_enabled on;
passenger_min_instances 1;
}
passenger_pre_start http://<%= sitedomain %>;
```
5. 使用如下內容創建 /etc/puppet/modules/rails/templates/nginx.conf.erb 文件:
```
events {
worker_connections 1024;
use epoll;
}
http {
passenger_root /usr/lib/ruby/gems/1.8/gems/passenger-<%=
passenger_version %>;
server_names_hash_bucket_size 64;
sendfile on;
tcp_nopush on;
tcp_nodelay off;
client_body_temp_path /var/spool/nginx-client-body 1 2;
client_max_body_size 100m;
include /opt/nginx/conf/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
$request" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"' ;
access_log /var/log/nginx/access.log main;
gzip on;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied any;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_types text/plain text/html text/css application/x-javascript
text/xml application/xml application/xml+rss text/javascript;
gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_vary on;
include /opt/nginx/sites-enabled/*;
}
```
6. 使用如下內容創建 /etc/puppet/modules/rails/files/nginx.init 文件:
```
#!/bin/sh
### BEGIN INIT INFO
# Provides: nginx
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts the nginx web server
# Description: starts nginx using start-stop-daemon
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/opt/nginx/sbin/nginx
NAME=nginx
DESC=nginx
test -x $DAEMON || exit 0
# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
. /etc/default/nginx
fi
set -e
# Return LSB status, grabbed from a newer lsb-base
status_of_proc () {
local pidfile daemon name status
pidfile=
OPTIND=1
while getopts p: opt ; do
case "$opt" in
p) pidfile="$OPTARG";;
esac
done
shift $(($OPTIND - 1))
if [ -n "$pidfile" ]; then
pidfile="-p $pidfile"
fi
daemon="$1"
name="$2"
status="0"
pidofproc $pidfile $daemon >/dev/null || status="$?"
if [ "$status" = 0 ]; then
log_success_msg "$name is running"
return 0
else
log_failure_msg "$name is not running"
return $status
fi
}
. /lib/lsb/init-functions
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
--exec $DAEMON -- $DAEMON_OPTS || true
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
--exec $DAEMON || true
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile \
/var/run/$NAME.pid --exec $DAEMON || true
sleep 1
start-stop-daemon --start --quiet --pidfile \
/var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
echo "$NAME."
;;
reload)
echo -n "Reloading $DESC configuration: "
start-stop-daemon --stop --signal HUP --quiet --pidfile \
/var/run/$NAME.pid --exec $DAEMON || true
echo "$NAME."
;;
status)
status_of_proc -p /var/run/$NAME.pid "$DAEMON" nginx \
&& exit 0 || exit $?
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|reload|forcereload|
status}" >&2
exit 1
;;
esac
exit 0
```
7. 添加如下代碼到一個節點:
```
rails::app { "furiouspigs":
sitedomain => "furiouspigs.com",
}
```
8. 運行 Puppet:
```
# puppet agent --test
info: Retrieving plugin
info: Caching catalog for cookbook.bitfieldconsulting.com
info: Applying configuration version '1309960678'
notice: /Stage[main]/Rails::Passenger/File[/opt/nginx]/ensure:
created
notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/sitesenabled]/
ensure: created
notice: /Stage[main]//Node[cookbook]/Rails::App[furiouspigs]/
File[/opt/nginx/sites-enabled/furiouspigs.conf]/ensure: created
notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf]/
ensure: created
notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf/
includes]/ensure: created
notice: /Stage[main]//Node[cookbook]/Rails::App[furiouspigs]/
File[/opt/nginx/conf/includes/furiouspigs.conf]/ensure: defined
content as '{md5}d41d8cd98f00b204e9800998ecf8427e'
notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/sitesavailable]/
ensure: created
notice: /Stage[main]//Node[cookbook]/Rails::App[furiouspigs]/
File[/opt/nginx/sites-available/furiouspigs.conf]/ensure: defined
content as '{md5}c1a4c2bc4e7381b1c2f88dfee004a594'
notice: /Stage[main]/Rails::Passenger/Exec[install-passenger]/
returns: executed successfully
notice: /Stage[main]/Rails::Passenger/Exec[install-passengernginx-
module]/returns: executed successfully
--- /opt/nginx/conf/nginx.conf 2011-07-06 14:04:33.231999538
+0000
+++ /tmp/puppet-file20110706-5343-k8ouds-0 2011-07-06
14:04:34.246867124 +0000
...
info: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf/nginx.
conf]: Filebucketed /opt/nginx/conf/nginx.conf to puppet with sum
34d60856b6570e9d59cd6eecde5da000
notice: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf/nginx.
conf]/content: content changed '{md5}34d60856b6570e9d59cd6eecde5
da000' to '{md5}72132deeb45e6ee5b83cd246dffefc5f'
info: /Stage[main]/Rails::Passenger/File[/opt/nginx/conf/nginx.
conf]: Scheduling refresh of Exec[reload-nginx]
notice: /Stage[main]/Rails::Passenger/Exec[reload-nginx]:
Triggered 'refresh' from 1 events
notice: Finished catalog run in 398.73 seconds
```
#### 工作原理
這個處方比本書中其他的處方更長、更復雜,因此需要更詳細的解釋。 如果你覺得這有些煩人,盡管去使用這個配方吧,不必擔心它是如何工作的。 稍后當你想學習更多詳細工作過程時,可以再回過頭來看這些解釋。
上面所有代碼的目的就是可以讓你寫出如下的實例化代碼:
```
rails::app { "furiouspigs":
sitedomain => "furiouspigs.com",
}
```
這需要不少幕后工作。我們需要安裝配置包含 Passenger 模塊的 Nginx, 配置應用程序的虛擬主機,包括所有應用程序特定的配置(比如重定向以及其他服務配置), 安裝 Ruby 和 Rubygems,安裝 Bundler,并創建要部署的應用程序所需的所有目錄。
##### Nginx 和 Passenger
此處分離出的 passenger.pp 文件用于安裝 Nginx 和 Passenger 所需的一切。 之前曾經提到過,Nginx 沒有像 Apache 一樣的動態模塊概念, 因此,你不能僅僅通過安裝發行版中的 Nginx 并安裝提供 Passenger 功能的軟件包來實現。 Nginx 必須與你想要的任何模塊一起編譯。
幸好,**Phusion** 社區里的好心人已經為我們提供了一個編譯腳本(passengerinstall-nginx-module)。 一旦你已經安裝了 Passenger 的 gem 包,這個腳本就會幫你完成編譯工作。 所以首先需要做的事就是安裝 Passenger 的 **gem**:
```
class rails::passenger {
$passenger_version = "3.0.7"
$passenger_dependencies = [ "build-essential",
"libcurl4-openssl-dev",
"libssl-dev",
"ruby",
"rubygems" ]
package { $passenger_dependencies: ensure => installed }
exec { "install-passenger":
command => "/usr/bin/gem install passenger
--version=${passenger_version}",
unless => "/usr/bin/gem list | /bin/grep passenger \
|/bin/grep ${passenger_version}",
require => [ Package["rubygems"], Package[$passenger_
dependencies] ],
timeout => "-1",
}
```
我們把要安裝的 Passenger 版本號設置在變量 $passenger_version 中, 因為 Nginx 需要知道 Passenger 的安裝路徑(路徑中包括版本號)。 所以我們會在 nginx.conf 模板中引用 $passenger_version 變量。
下一步是運行 passenger-install-nginx-module 腳本:
```
exec { "install-passenger-nginx-module":
command => "/usr/lib/ruby/gems/1.8/gems/passenger-${passenger_
version}/bin/passenger-install-nginx-module --auto --autodownload
--prefix=/opt/nginx",
creates => "/opt/nginx/sbin/nginx",
require => Exec["install-passenger"],
timeout => "-1",
}
```
> 
> 你應該注意到了,此處 **gem** 的路徑是固定的 /usr/lib/ruby/gems/1.8/gems。 這有些脆弱?—?在大部分生產基礎設施中,我使用 **RVM** 管理 Ruby 版本和不同版本的 **gemsets**, 這就解決了由于使用固定路徑帶來的脆弱性。 然而,添加 RVM 會使本處方變得難于理解,所以我將使用 RVM 的部分放在 更多用法 小節中。 一旦你熟悉了這個處方,就可以修改它,使之適合你自己的需求,包括整合 RVM。
這也就意味著,如果你使用 Ruby 1.9,這個處方不會工作,當本書出版后你讀到此處時很可能會發生這種情況。 如果是這樣,或者你遇到其他問題,請手工運行 gem contents passenger 命令之后查找 passenger-installnginx-module 腳本的路徑。
下一步,我們創建了 Nginx 配置文件所需的目錄結構:
```
file { [ "/opt/nginx",
"/opt/nginx/conf",
"/opt/nginx/conf/includes",
"/opt/nginx/sites-enabled",
"/opt/nginx/sites-available",
"/var/log/nginx" ]:
ensure => directory,
owner => "www-data",
group => "www-data",
}
```
我們要刪除默認的 Nginx 虛擬主機配置,否則可能會干擾我們要創建的虛擬主機。 這可以通過如下代碼實現:
```
file { "/opt/nginx/sites-enabled/default":
ensure => absent,
require => Exec["install-passenger-nginx-module"],
}
```
實際上,如果你從源代碼構建 Nginx 或是通過 Passenger 構建(本例中的方法),這是不需要的, 但是如果要想使本處方也適用于發行版的 Nginx 軟件包,這會是有益的。
下面是 Nginx 的主配置文件:
```
file { "/opt/nginx/conf/nginx.conf":
content => template("rails/nginx.conf.erb"),
notify => Exec["reload-nginx"],
require => Exec["install-passenger-nginx-module"],
}
```
主配置文件使用 nginx.conf.erb 模板生成,因為我們需要插入之前定義的 Passenger 版本號:
```
passenger_root /usr/lib/ruby/gems/1.8/gems/passenger-<%= passenger_
version %>;
```
否則,它就是一個標準的 Nginx 配置,你也可以在模板中添加任何你的服務器所需的特殊參數。
因為我們沒有使用發行版提供的軟件包,所以我們需要為節點應用一個 init 腳本 (改編自 Ubuntu 版本,僅做了輕微的修改):
```
file { "/etc/init.d/nginx":
source => "puppet:///modules/rails/nginx.init",
mode => "700",
require => Exec["install-passenger-nginx-module"],
}
```
為了運行 Nginx 服務需要如下代碼:
```
service { "nginx":
enable => true,
ensure => running,
require => File["/etc/init.d/nginx"],
}
```
要確保錯誤的配置不會使服務器宕機,配置文件的改變會通知如下的 “配置檢查和重載” 資源:
```
exec { "reload-nginx":
command => "/opt/nginx/sbin/nginx -t \
&& /etc/init.d/nginx reload",
refreshonly => true,
require => Exec["install-passenger-nginx-module"],
}
```
##### Rails
你已經設置好了 Passenger 和 Nginx,接下來配置 **Rails** 需求的類:
```
class rails {
include rails::passenger
package { "bundler":
provider => gem,
ensure => installed,
}
}
```
**Bundler** 是一個管理應用程序或解決 gem 依賴關系的工具。 你可以使用手工方式(或通過 Puppet)指定要安裝的所有 gem 包以及依賴的包, 取代這種方式的更好辦法是使用 Bundler 來實現,它是 Rails 部署的一部分。 例如,你應該注意到了,我們沒有安裝 rails 的 gem;這通常是通過 Bundler 安裝的, 或者在應用程序的 vendor 目錄中已經提供了一份特定版本的 rails。 如果你沒有使用 Bundler,或者你需要為你的 Rails 應用程序設置一些額外的依賴, 請在這個類中使用 Puppet 的 package 資源做相應的配置來安裝它們。
rails 類的的主要部分是 define 函數 app, 對于你要管理的每個應用程序,它都會被實例化一次:
```
define app( $sitedomain ) {
include rails
```
為應用程序做的第一件事是安裝 Nginx 虛擬主機配置文件,它由 app.conf.erb 模板生成:
```
file { "/opt/nginx/sites-available/${name}.conf":
content => template("rails/app.conf.erb"),
require => File["/opt/nginx/sites-available"],
}
file { "/opt/nginx/sites-enabled/${name}.conf":
ensure => link,
target => "/opt/nginx/sites-available/${name}.conf",
require => File["/opt/nginx/sites-enabled"],
notify => Exec["reload-nginx"],
}
```
虛擬主機配置文件的模板相當小:
```
server {
listen 80;
root /var/www/<%= name %>/current/public;
server_name <%= sitedomain %>;
access_log /var/log/nginx/<%= name %>.access.log;
error_log /var/log/nginx/<%= name %>.error.log;
passenger_enabled on;
passenger_min_instances 1;
}
passenger_pre_start http://<%= sitedomain %>;
```
通常一個應用程序需要特定的 Nginx 配置指令,比如 redirects。 你可以在 Rails 模塊中添加一個名為 files/furiouspigs.conf 的文件來包含這些配置指令。 Puppet 會從如下的這段代碼找到這個文件,并分發給節點:
```
file { "/opt/nginx/conf/includes/${name}.conf":
source => [ "puppet:///modules/rails/${name}.conf",
"puppet:///modules/rails/empty.conf" ],
notify => Exec["reload-nginx"],
}
```
注意這個文件使用了多個源,第二個源 empty.conf 確保 Puppet 不會因為應用程序指定的配置文件不存在而抱怨。
最后我們要確保為準備部署的標準 Rails 目錄結構配置 www-data 用戶屬主及適當的權限(775)。 如果你的 Nginx 以及部署的應用程序以不同的用戶身份執行,請使用你的用戶名替換所有的 www-data。
```
file { [ "/var/www",
"/var/www/${name}",
"/var/www/${name}/releases",
"/var/www/${name}/shared",
"/var/www/${name}/shared/config",
"/var/www/${name}/shared/log",
"/var/www/${name}/shared/system" ]:
ensure => directory,
mode => 775,
owner => "www-data",
group => "www-data",
}
}
}
```
#### 更多用法
使用 Puppet 管理 Rails 應用程序,你可能還需要考慮一些其他的事情。
##### RVM
正如我之前所提到的,使用 RVM 管理多版本 Ruby 和多版本的 gemsets 是一種強大的解決方案。 當然,使用 RVM 也帶來了自身的有趣問題?—?RVM 的開發活躍,其主體經常變化。 無論如何,RVM 為我們帶來的好處還是比其帶來的麻煩要多的多。 所以,我建議你對生產線上的 Rails 站點,或許可以通過類似這樣的代碼應用 RVM:
```
class rails::rvm {
package { [ "autoconf",
"bison",
"curl",
"libreadline-dev",
"subversion",
"zlib1g-dev" ]:
ensure => installed
}
file { "/usr/local/bin/rvm-install-system-wide":
source => "puppet:///modules/rails/rvm-install-system-wide",
mode => "700",
}
exec { "install-rvm":
command => "/usr/local/bin/rvm-install-system-wide",
creates => "/usr/local/bin/rvm",
require => [ Package["curl"], Package["subversion"],
File["/usr/local/bin/rvm-install-system-wide"] ],
logoutput => on_failure,
}
append_if_no_such_line { "setup-rvm-shell-environment":
file => "/etc/bash.bashrc",
line => "[[ -s /usr/local/rvm/scripts/rvm ]] \
&& . /usr/local/rvm/scripts/rvm",
}
}
```
rvm-install-system-wide 腳本來自 RVM 網站: [https://rvm.beginrescueend.com/install/rvm](https://rvm.beginrescueend.com/install/rvm) 。
##### 日志滾動
在生產環境中你可能會需要為 Nginx 和 Rails 生成的日志文件添加 logrotate 配置片段, 以確保這些日志不會逐步占滿你的磁盤。因為篇幅限制和保持簡單的原因,本例省略了對日志滾動的配置。
##### 數據庫
本處方中,未對 Rails 應用程序創建任何數據庫及訪問數據庫的用戶; 配置何種數據庫取決于你團隊的開發者正在使用何種數據庫(MySQL、Postgres、MongoDB 等), 你需要自行添加管理數據庫的 Puppet 代碼。如果使用的是 MySQL, 你可以參考 [創建 MySQL 數據庫及用戶](#ch07sec04) 一節的內容并作適當的改寫。
##### SSL 證書
一些應用程序會需要 SSL 證書并為 **vhost** 配置安全的 URLs,例如:處理網上支付。 這已超出了本處方的講解范圍,但你應該可以發現添加所需的代碼并不困難。 你可以在 rails::app 函數的定義中添加一個可選參數,例如:
```
define app( $sitedomain, $ssl = false ) {
```
并添加如下代碼處理這個參數:
```
if $ssl {
file { "/etc/ssl/certs/${name}.crt":
source => "puppet:///modules/rails/${name}.crt",
}
}
```
然后,只要使用如下的代碼對你的應用程序進行實例化即可:
```
rails::app { "irritatedbadgers":
sitedomain => "irritatedbadgers.com",
ssl => true,
}
```
- 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
- 使用公共模塊
- 使用外部節點分類器
- 創建自定義的資源類型
- 創建自定義的提供者