

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

# 步骤 3：创建和部署自定义说明书
<a name="other-services-redis-cookbook"></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 支持 团队联系。

目前，堆栈的功能尚不完备；您需要允许您的应用程序访问 Redis 服务器。最灵活的方法是在应用程序的 `config` 子文件夹中放置一个包含访问信息的 YAML 文件。这样，应用程序即可从该文件中获取信息。使用此方法，您可以更改连接信息，而无需重新编写和重新部署应用程序。在本示例中，文件应命名为 `redis.yml` 并包含 ElastiCache 集群的主机名和端口，如下所示：

```
host: cache-cluster-hostname
port: cache-cluster-port
```

你可以手动将这个文件复制到你的服务器上，但更好的方法是实现一个 Chef *配方*来生成文件，然后让 OpsWorks Stacks 在每台服务器上运行这个配方。Chef 配方是专门的 Ruby 应用程序， OpsWorks Stacks 使用它在实例上执行任务，例如安装软件包或创建配置文件。配方打包在*说明书*中，说明书可以包含多个配方和相关的文件，例如配置文件的模板。食谱放在存储库中，例如 GitHub，并且必须具有标准的目录结构。如果您还没有自定义说明书存储库，请参阅[说明书存储库](workingcookbook-installingcustom-repo.md)，以了解如何进行设置的信息。

在本示例中，将使用以下内容，向您的说明书存储库中添加一个名为 `redis-config` 的说明书：

```
my_cookbook_repository
  redis-config
    recipes
      generate.rb
    templates
      default
        redis.yml.erb
```

`recipes` 文件夹包含一个名为 `generate.rb` 的配方，该配方从 `redis.yml.erb` 生成应用程序的配置文件，如下所示：

```
node[:deploy].each do |app_name, deploy_config|
  # determine root folder of new app deployment
  app_root = "#{deploy_config[:deploy_to]}/current"

  # use template 'redis.yml.erb' to generate 'config/redis.yml'
  template "#{app_root}/config/redis.yml" do
    source "redis.yml.erb"
    cookbook "redis-config"

    # set mode, group and owner of generated file
    mode "0660"
    group deploy_config[:group]
    owner deploy_config[:user]

    # define variable “@redis” to be used in the ERB template
    variables(
      :redis => deploy_config[:redis] || {}
    )

    # only generate a file if there is Redis configuration
    not_if do
      deploy_config[:redis].blank?
    end
  end
end
```

配方取决于来自 St [ac OpsWorks ks 堆栈配置和部署 JSON](workingcookbook-json.md) 对象的数据，该对象安装在每个实例上，包含有关堆栈和任何已部署应用程序的详细信息。该对象的 `deploy` 节点具有以下结构：

```
{
   ...
  "deploy": {
    "app1": {
      "application" : "short_name",
      ...
    }
    "app2": {
      ...
    }
    ...
  }
}
```

此部署节点包含一组嵌入式 JSON 对象 (每个已部署应用程序对应一个对象，且对象以应用程序的短名称命名)。每个应用程序对象包含一组定义应用程序配置的属性，例如文档根和应用程序类型。关于 deploy 属性的列表，请参阅 [deploy 属性](attributes-json-deploy.md)。配方可以使用 Chef 属性语法来表示堆栈配置和部署 JSON 值。例如，`[:deploy][:app1][:application]` 表示 app1 应用程序的短名称。

对于 `[:deploy]` 中的每个应用程序，该配方执行关联的代码块，其中 `deploy_config` 表示应用程序属性。该配方首先将 `app_root` 设置为应用程序的根目录 `[:deploy][:app_name][:deploy_to]/current`。然后，它使用 Chef [模板资源](https://docs.chef.io/chef/resources.html#template)从 `redis.yml.erb` 生成配置文件，并将该文件放在 `app_root/config` 中。

 配置文件通常是从模板创建的，而且许多 (即便不是大多数) 设置是由 Chef *属性*定义。借助这些属性，您可以使用自定义 JSON 更改设置 (如下文所述)，而不是重写模板文件。`redis.yml.erb` 模板包含以下内容：

```
host: <%= @redis[:host] %>
port: <%= @redis[:port] || 6379 %>
```

<%... %> 元素是表示属性值的占位符。
+ `<%= @redis[:host] %>` 表示 `redis[:host]` 的值，即缓存集群的主机名。
+ `<%= @redis[:port] || 6379 %>` 表示 `redis[:port]` 的值，如果未定义该属性，则表示默认端口值 6379。

`template` 资源的工作方式如下所示：
+ `source` 和 `cookbook` 分别指定模板和说明书名称。
+ `mode`、`group` 和 `owner` 为配置文件提供与应用程序相同的访问权限。
+ `variables` 部分将模板中使用的 `@redis` 变量设置为应用程序的 `[:redis]` 属性值。

  通过使用自定义 JSON 来设置 `[:redis]` 属性的值，如下文所述；它不是标准应用程序属性之一。
+ `not_if` 指令可确保该配方在已存在配置文件的情况下不会再生成配置文件。

编写说明书后，您必须将其部署到每个实例的说明书缓存。此操作并不运行该配方，它只是在堆栈的实例上安装新说明书。一般情况下，可通过将配方分配到某个层的生命周期事件来运行该配方，如下文所述。

**部署自定义说明书**

1. 在 “**堆栈 OpsWorks 堆栈**” 页面上，单击 “**堆栈设置**”，然后单击 “**编辑”**。

1. 在 **Configuration Management** 部分中，将 **Use custom Chef cookbooks** 设置为 **Yes**，输入说明书存储库信息，然后单击 **Save** 以更新堆栈配置。  
![\[Configuration form for custom Chef cookbooks with repository details and options.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/redis_walkthrough_cookbook.png)

1. 在 **Stack** 页面上，单击 **Run Command**，选择 **Update Custom Cookbooks** 堆栈命令，然后单击 **Update Custom Cookbooks** 以将新说明书安装到实例的说明书缓存中。  
![\[Run Command interface showing Update Custom Cookbooks option and instance selection for Rails App Server.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/redis_walkthrough_command.png)

如果您修改您的说明书，只需再次运行 **Update Custom Cookbooks** 来安装更新版本。有关此过程的更多信息，请参阅[安装自定义说明书](workingcookbook-installingcustom-enable.md)。