

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 配方
<a name="workingcookbook-installingcustom-components-recipes"></a>

**重要**  
该 AWS OpsWorks Stacks 服务于 2024 年 5 月 26 日终止，新客户和现有客户均已禁用。我们强烈建议客户尽快将其工作负载迁移到其他解决方案。如果您对迁移有疑问，请通过 re [AWS : Post 或通过 Pre](https://repost.aws/) mium Su [AWS pp](https://aws.amazon.com/support) ort 与 AWS 支持 团队联系。

配方是用于定义系统配置的 Ruby 应用程序。它们可安装程序包、从模板创建配置文件、执行 shell 命令、创建文件和目录等。当实例发生[生命周期事件](workingcookbook-events.md)时，你通常会让 OpsWorks Stacks 自动执行配方，但你也可以使用 E [xecute Recipes 堆栈命令](workingcookbook-executing.md)随时显式运行它们。有关更多信息，请参阅[关于配方](http://docs.chef.io/recipes.html)。

配方通常主要包含一系列*资源*，每种资源均表示系统的某方面的所需状态。每种资源包含一组属性，用于定义所需状态并指定要采取的操作。Chef 将每种资源与执行操作的相应*提供商*进行关联。有关更多信息，请参阅[资源和提供商参考](https://docs.chef.io/resource.html)。

`package` 资源可帮助您管理 Linux 实例上的软件包。下面的示例将安装 Apache 程序包。

```
...
package 'apache2' do
  case node[:platform]
  when 'centos','redhat','fedora','amazon'
    package_name 'httpd'
  when 'debian','ubuntu'
    package_name 'apache2'
  end
  action :install
end
...
```

Chef 针对平台使用合适的程序包提供商。通常只向资源属性分配一个值，但您可以使用 Ruby 逻辑运算执行条件分配。该示例使用一个 `case` 运算符，该运算符使用 `node[:platform]` 识别实例的操作系统并相应地设置 `package_name` 属性。您可以通过使用标准 Chef 节点语法将属性插入配方中，然后 Chef 会将它替换为关联的值。您可以使用节点对象中的任何属性，而不仅仅是说明书的属性。

在确定合适的程序包名称后，代码段会以用于安装程序包的 `install` 操作结束。此资源的其他操作包括 `upgrade` 和 `remove`。有关更多信息，请参阅[程序包](https://docs.chef.io/chef/resources.html#id150)。

将复杂的安装和配置任务拆分为一个或多个子任务 (每个子任务作为单独的配方执行) 并且在适当的时间让您的主配方运行这些子任务通常很有用。以下示例显示了沿袭前一个示例的代码行：

```
include_recipe 'apache2::service'
```

要让配方执行子配方，请使用 `include_recipe` 关键字并后跟配方名称。使用标准 Chef `CookbookName::RecipeName` 语法标识配方，其中 `RecipeName` 省略了 `.rb` 扩展名。

**注意**  
`include_recipe` 语句在主配方中的此位置有效地执行配方。但是，实际发生的情况是，Chef 在执行主配方前会将每个 `include_recipe` 语句替换为指定配方的代码。

`directory` 资源表示一个目录，如用于包含程序包的文件的目录。以下 `default.rb` 资源创建 Linux 日志目录。

```
directory node[:apache][:log_dir] do
    mode 0755
    action :create
end
```

此日志目录在说明书的一个属性文件中进行定义。资源将目录的模式指定为 0755 并使用 `create` 操作来创建目录。有关更多信息，请参阅[目录](https://docs.chef.io/chef/resources.html#directory)。您还可以将此资源与 Windows 实例一起使用。

`execute` 资源表示命令，如 shell 命令或脚本。以下示例生成 module.load 文件。

```
execute 'generate-module-list' do
  if node[:kernel][:machine] == 'x86_64'
    libdir = 'lib64'
  else
    libdir = 'lib'
  end
  command "/usr/local/bin/apache2_module_conf_generate.pl /usr/#{libdir}/httpd/modules /etc/httpd/mods-available"
  action :run
end
```

资源首先确定 CPU 类型。`[:kernel][:machine]` 是 Chef 生成的用来表示各种系统属性的另一种自动属性（在此例中为 CPU 类型）。然后，它指定命令 (Perl 脚本) 并使用 `run` 操作运行该脚本，从而生成 module.load 文件。有关更多信息，请参阅 [execute](https://docs.chef.io/chef/resources.html#execute)。

`template` 资源表示要从说明书的模板文件之一生成的一种文件，通常是配置文件。以下示例从在[模板](workingcookbook-installingcustom-components-templates.md)中所讨论的 `apache2.conf.erb` 模板中创建 `httpd.conf` 配置文件。

```
template 'apache2.conf' do
  case node[:platform]
  when 'centos','redhat','fedora','amazon'
    path "#{node[:apache][:dir]}/conf/httpd.conf"
  when 'debian','ubuntu'
    path "#{node[:apache][:dir]}/apache2.conf"
  end
  source 'apache2.conf.erb'
  owner 'root'
  group 'root'
  mode 0644
  notifies :restart, resources(:service => 'apache2')
end
```

资源将基于实例的操作系统确定生成的文件的名称和位置。然后，它将 `apache2.conf.erb` 指定为要用于生成文件的模板并设置文件的所有者、组和模式。它运行 `notify` 操作来通知代表 Apache 服务器的 `service` 资源重新启动该服务器。有关更多信息，请参阅[模板](https://docs.chef.io/chef/resources.html#template)。