

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 配方結構
<a name="cookbooks-101-basics-structure"></a>

**重要**  
 AWS OpsWorks Stacks 此服務已於 2024 年 5 月 26 日終止，並已針對新客戶和現有客戶停用。我們強烈建議客戶盡快將其工作負載遷移至其他解決方案。如果您對遷移有任何疑問，請透過 [AWS re：Post](https://repost.aws/) 或透過 [AWS Premium Support](https://aws.amazon.com/support) 聯絡 AWS 支援 團隊。

技術指南主要是一組可在執行個體上執行各種任務的「配方」**。若要釐清如何實作配方，查看簡單的範例會有所幫助。以下是內建 [HAProxy layer](layers-haproxy.md) 的設定配方。這個時候只要關注整體結構，不必太過擔心詳細資訊，後續範例會有相關說明。

```
package 'haproxy' do
  action :install
end

if platform?('debian','ubuntu')
  template '/etc/default/haproxy' do
    source 'haproxy-default.erb'
    owner 'root'
    group 'root'
    mode 0644
  end
end

include_recipe 'haproxy::service'

service 'haproxy' do
  action [:enable, :start]
end

template '/etc/haproxy/haproxy.cfg' do
  source 'haproxy.cfg.erb'
  owner 'root'
  group 'root'
  mode 0644
  notifies :restart, "service[haproxy]"
end
```

**注意**  
如需此範例和其他範例的工作配方和相關檔案，請參閱 [OpsWorks Stacks 內建配方](https://github.com/aws/opsworks-cookbooks)。

此範例強調關鍵的配方元素，下列各節中會詳加說明。

**Topics**
+ [Resources](#cookbooks-101-basics-structure-resources)
+ [流量控制](#cookbooks-101-basics-structure-ruby)
+ [隨附的配方](#cookbooks-101-basics-structure-include)

## Resources
<a name="cookbooks-101-basics-structure-resources"></a>

配方的組成主要是一組 Chef「資源」**。它們每一個都會指定特定方面的執行個體最終狀態，例如要安裝的套件或要啟動的服務。此範例有四項資源：
+ `package` 資源，在本範例中代表已安裝的套件，即 [HAProxy 伺服器](http://haproxy.1wt.eu/)。
+ `service` 資源，在本範例中代表服務，即 HAProxy 服務。
+ 兩個 `template` 資源，在本範例中代表要從指定的範本建立的檔案，即兩個 HAProxy 組態檔案。

資源以宣告的方式指定執行個體狀態。在幕後，每項資源都有一個相關聯的「提供者」**，執行所需的任務，例如安裝套件、建立及設定目錄、啟動服務等等。如果任務的詳細資訊取決於特定的作業系統，則資源會有多個提供者，並會使用最適合系統的那一個。例如，在 Red Hat Linux 系統中，`package` 提供者會使用 `yum` 安裝套件。在 Ubuntu Linux 系統中，`package` 提供者會使用 `apt-get`。

您要將資源實作為具有下列一般格式的 Ruby 程式碼區塊。

```
resource_type "resource_name" do
  attribute1 'value1'
  attribute2 'value2'
  ...
  action :action_name
  notifies : action 'resource'
end
```

這些元素是：

**Resource Type (資源類型)**  
(必要) 本範例包括三種資源類型：`package`、`service` 和 `template`。

**資源名稱**  
(必要) 此名稱可識別特定的資源，有時用為其中一個屬性的預設值。在此範例中，`package` 代表名為 `haproxy` 的套件資源，而第一個 `template` 資源代表名為 `/etc/default/haproxy` 的組態檔案。

**屬性**  
(選用) 這些屬性會指定資源組態，並會隨著資源類型及您設定資源的方式而不同。  
+ 此範例的 `template` 資源會明確定義一組屬性，指定已建立的檔案來源、擁有者、群組和模式。
+ 此範例的 `package` 和 `service` 資源不會明確定義任何屬性。

  資源名稱一般是必要屬性的預設值，有時候只需要它就夠了。例如，資源名稱是 `package` 資源之 `package_name` 屬性的預設值，它是唯一需要的屬性。
也有一些特殊化的屬性，稱之為保護屬性，它們會指定資源提供者何時採取動作。例如，`only_if` 屬性只有在符合指定條件時，才會指示資源提供者採取動作。HAProxy 配方不使用保護屬性，但下列幾個範例會使用它們。

**動作和通知**  
(選用) 動作和通知會指定提供者要執行的任務。  
+ `action` 指示提供者採取指定的動作，例如安裝或建立。

  每項資源都有一組取決於特定資源的動作，其中一個是預設動作。在此範例中，`package` 資源的動作是 `install`，它會指示提供者安裝套件。第一項 `template` 資源沒有 `action` 元素，所以提供者採取預設的 `create` 動作。
+ `notifies` 指示另一項資源的提供者執行動作，但只有在資源狀態變更後。

  `notifies` 通常搭配 `template` 和 `file` 等資源使用，執行的任務如在修改組態檔案後重新啟動服務。資源沒有預設的通知。如果您想要有通知，資源必須有明確的 `notifies` 元素。在 HAProxy 配方中，如果相關聯的組態檔案已變更，第二項 `template` 資源會通知 haproxy `service` 資源重新啟動 HAProxy 服務。

資源有時取決於作業系統。
+ 有些資源只能用於 Linux 或 Windows 系統。

  例如，[package](https://docs.chef.io/chef/resources.html#package) 會在 Linux 系統上安裝套件，而在 Windows 系統上安裝套件要使用 [windows\$1package](https://docs.chef.io/chef/resources.html#windows-package)。
+ 有些資源可搭配任何作業系統，但需要特定系統的專屬屬性。

  例如，[file](https://docs.chef.io/chef/resources.html#file) 資源可用於 Linux 或 Windows 系統，但設定許可時使用不同的屬性集。

如需標準資源的說明，包括每項資源的可用屬性、動作和通知，請參閱[關於資源和提供者](https://docs.chef.io/resource.html)。

## 流量控制
<a name="cookbooks-101-basics-structure-ruby"></a>

因為配方是 Ruby 應用程式，所以您可以使用 Ruby 控制結構在配方中納入流程控制。例如，您可以使用 Ruby 條件邏輯，讓配方在不同的系統中有不同的行為。HAProxy 配方包含的 `if` 區塊可使用 `template` 資源建立組態檔案，但只有當配方在 Debian 或 Ubuntu 系統中執行時才可以。

另一個常見的情況是使用迴圈以不同的屬性設定來多次執行資源。例如，您可以使用迴圈以不同的目錄名稱多次執行 `directory` 資源，來建立一組目錄。

**注意**  
如果您不熟悉 Ruby，請參閱[僅足夠適用於 Chef 的 Ruby](https://docs.chef.io/just_enough_ruby_for_chef.html)，其中包含多數配方需要知道的內容。

## 隨附的配方
<a name="cookbooks-101-basics-structure-include"></a>

`include_recipe` 在您的程式碼中包含其他配方，讓您模組化您的配方，並在多種配方中重複使用相同的程式碼。當您執行主機配方時，Chef 會先使用指定的配方程式碼取代每個 `include_recipe` 元素，再執行主機配方。您使用標準的 Chef `cookbook_name::recipe_name` 語法來納入配方，其中 `recipe_name` 會省略 `.rb` 副檔名。此範例包含的配方 `haproxy::service`，代表 HAProxy 服務。

**注意**  
如果您在於 Chef 11.10 和更新版本上執行的配方中使用 `include_recipe` 來納入其他技術指南的配方，即必須使用 `depends` 陳述式在技術指南的 `metadata.rb` 檔案中宣告相依性。如需詳細資訊，請參閱[實作配方：Chef 11.10](workingcookbook-chef11-10.md)。