

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

# 堆叠食谱入 OpsWorks 门
<a name="gettingstarted-cookbooks"></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 支持 团队联系。

生产级 OpsWorks Stacks 堆栈通常需要一些自定义，这通常意味着要实现自定义 Chef 食谱。*说明书* 是一个程序包文件，其中包含配置信息（如称为*配方*的指令）。*配方* 是一组指令 (包含一个或多个指令)，使用 Ruby 语言语法编写，用于指定要使用的资源以及这些资源的使用顺序。*资源*（在 Chef 中使用）是配置策略的语句。本演练提供了实现 Stacks 的 Chef 食谱的基本 OpsWorks 介绍。要了解有关 Chef、说明书、配方和资源的更多信息，请参阅[后续步骤](gettingstarted-cookbooks-next-steps.md)中的链接。

本演练主要介绍如何创建您自己的说明书。您还可以使用可在 [Chef Supermarket](https://supermarket.chef.io) 等网站上找到的社区提供配方。为了帮助您开始使用社区说明书，我们在本演练后面的部分中包括了关于使用 Chef Supermarket 中的社区说明书的说明。

在开始本演练之前，请完成几个设置步骤。如果您已经完成本章中的任何其他演练 (如[入门：示例](gettingstarted-intro.md))，则您就满足了本演练的先决条件，可以跳至[开始此演练](gettingstarted-cookbooks-create-cookbook.md)。否则，请确保完成[先决条件](gettingstarted-intro-prerequisites.md)，然后再返回到此演练。

**Topics**
+ [第 1 步：创建说明书](gettingstarted-cookbooks-create-cookbook.md)
+ [第 2 步：创建堆栈及其组件](gettingstarted-cookbooks-create-stack.md)
+ [第 3 步：运行并测试配方](gettingstarted-cookbooks-test-recipe.md)
+ [第 4 步：更新说明书以安装程序包](gettingstarted-cookbooks-install-package.md)
+ [第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)
+ [第 6 步：更新说明书以添加用户](gettingstarted-cookbooks-add-user.md)
+ [第 7 步：更新说明书以创建目录](gettingstarted-cookbooks-create-directory.md)
+ [第 8 步：更新说明书以创建并复制文件](gettingstarted-cookbooks-create-file.md)
+ [第 9 步：更新说明书以运行命令](gettingstarted-cookbooks-run-command.md)
+ [第 10 步：更新说明书以运行脚本](gettingstarted-cookbooks-run-script.md)
+ [第 11 步：更新说明书以管理服务](gettingstarted-cookbooks-manage-service.md)
+ [第 12 步：更新说明书以使用自定义 JSON](gettingstarted-cookbooks-custom-json.md)
+ [第 13 步：更新说明书以使用数据包](gettingstarted-cookbooks-data-bags.md)
+ [第 14 步：更新说明书以使用迭代](gettingstarted-cookbooks-iteration.md)
+ [第 15 步：更新说明书以使用条件逻辑](gettingstarted-cookbooks-conditional-logic.md)
+ [第 16 步：更新说明书以使用社区说明书](gettingstarted-cookbooks-community-cookbooks.md)
+ [步骤 17：(可选) 清除](gettingstarted-cookbooks-clean-up.md)
+ [后续步骤](gettingstarted-cookbooks-next-steps.md)

# 第 1 步：创建说明书
<a name="gettingstarted-cookbooks-create-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 支持 团队联系。

首先，创建一个说明书。此说明书在一开始不会起太多作用，但它可以作为本演练其余部分的基础。

**注意**  
此步骤演示如何手动创建说明书。使用 Chef 开发工具包 ([Chef DK](https://docs.chef.io/#chef-dk-title))，您可以在本地工作站上运行 [https://docs.chef.io/ctl_chef.html#chef-generate-cookbook](https://docs.chef.io/ctl_chef.html#chef-generate-cookbook) 命令，节省创建说明书所需的时间。但是，此命令创建的一些文件夹和文件在本演练中是用不到的。

**创建说明书**

1. 在您的本地工作站上，创建一个名为 `opsworks_cookbook_demo` 的目录。您可以使用一个不同的名称，但务必在本演练过程中将其替换为 `opsworks_cookbook_demo`。

1. 在 `opsworks_cookbook_demo` 目录中，使用文本编辑器创建一个名为 `metadata.rb` 的文件。添加以下代码以指定说明书的名称。有关 `metadata.rb` 的更多信息，请参阅 Chef 网站上的 [metadata.rb](https://docs.chef.io/config_rb_metadata.html)。

   ```
   name "opsworks_cookbook_demo"
   ```

1. 在 `opsworks_cookbook_demo` 目录中，创建名为 `recipes` 的子目录。此子目录包含您为本演练的说明书创建的所有配方。

1. 在 `recipes` 目录中创建名为 `default.rb` 的文件。此文件包含一个与之同名但没有文件扩展名的配方：`default`。将以下单独的代码行添加到 `default.rb` 文件中。此代码是一个一行配方，当配方运行时，将在日志中显示一条简单的消息：

   ```
   Chef::Log.info("********** Hello, World! **********")
   ```

1. 在终端处或在命令提示符下，使用 **tar** 命令创建一个名为 `opsworks_cookbook_demo.tar.gz` 的文件，该文件包含 `opsworks_cookbook_demo` 目录及其内容。例如：

   ```
   tar -czvf opsworks_cookbook_demo.tar.gz opsworks_cookbook_demo/
   ```

   您可以使用一个不同的文件名称，但务必在本演练过程中将其替换为 `opsworks_cookbook_demo.tar.gz`。
**注意**  
当您在 Windows 上创建 `tar` 文件时，顶级目录必须是说明书的父目录。本演练已经在 Linux (使用 `tar` 程序包提供的 **tar** 命令) 和 Windows (使用 [Git Bash](https://git-for-windows.github.io/) 提供的 **tar** 命令)上经过了测试。使用其他命令或程序来创建压缩的 TAR (.tar.gz) 文件可能不会达到预期效果。

1. 创建一个 S3 存储桶或使用现有存储桶。有关更多信息，请参阅[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingABucket.html)。

1. 将 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。有关更多信息，请参阅[将对象添加到存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PuttingAnObjectInABucket.html)。

您现在拥有一个您将在本演练的整个过程中都要用到的说明书。

在[下一步](gettingstarted-cookbooks-create-stack.md)中，您将创建一个 OpsWorks Stacks 堆栈，稍后将使用该堆栈来上传食谱和运行食谱的食谱。

# 第 2 步：创建堆栈及其组件
<a name="gettingstarted-cookbooks-create-stack"></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 支持 团队联系。

创建 OpsWorks 堆栈及其组件，包括一个层和一个实例。在稍后的步骤中，您需要将您的说明书上传到实例中，然后在该实例上运行说明书的配方。

**要创建 堆栈，请执行以下操作：**

1. 通过 [https://console.aws.amazon.com/](https://console.aws.amazon.com/opsworks)opsworks 登录 OpsWorks Stacks 控制台。

1. 执行以下任一操作 (如果适用)：
   + 如果显示 “**欢迎使用 OpsWorks 堆栈**” 页面，请选择 “**添加您的第一个堆栈**” 或 “**添加您的第一个 OpsWorks 堆栈**”（两个选项的作用相同）。这将显示 **Add stack** 页面。
   + 如果显示**OpsWorks 控制面板**页面，请选择**添加堆栈**。这将显示 **Add Stack** 页面。

1. 选择 **Chef 12 stack**。

1. 在 **Stack name (堆栈名称)** 框中，键入堆栈的名称，例如：**MyCookbooksDemoStack**。您可以键入一个不同的名称，但务必在本演练过程中将其替换为 `MyCookbooksDemoStack`。

1. 对于**区域**，选择**美国西部（俄勒冈）**。

1. 对于 **VPC**，请执行下列操作之一：
   + 如果 VPC 可用，请选择它。有关更多信息，请参阅 [在 VPC 中运行堆栈](workingstacks-vpc.md)。
   + 否则，请选择 **No VPC (无 VPC)**。

1. 对于 **Use custom Chef cookbooks**，选择 **Yes**。

1. 对于 **Repository type**，选择 **S3 Archive**。
**注意**  
在 [入门：Linux](gettingstarted-linux.md) 演练中，您选择了 **Http Archive**。但在这里，请务必选择 **S3 Archive**。

1. 对于 **Repository URL**，键入 S3 中的 `opsworks_cookbook_demo.tar.gz` 文件的路径。要获取路径，请在 S3 控制台中选择 `opsworks_cookbook_demo.tar.gz` 文件。在 **Properties** 窗格中，复制 **Link** 字段的值。(它应类似于以下内容：`https://s3.amazonaws.com/amzn-s3-demo-bucket/opsworks_cookbook_demo.tar.gz`。)

1. 默认情况下，您的 S3 存储桶是私有的，如果是这样，则对于 **Access key ID** 和 **Secret access key**，请键入您为本演练使用的 IAM; 用户的访问密钥 ID 和秘密访问密钥。有关更多信息，请参阅[编辑对象许可](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EditingPermissionsonanObject.html)和[与其他用户共享对象](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html)。

1. 对以下项目保留默认值：
   + **Default Availability Zone** (**us-west-2a**)
   + **默认操作系统**（**Linux** 和 **Amazon Linux 2016.09**）
   + **Default SSH key** (**Do not use a default SSH key**)
   + **Stack color** (深蓝色)

1. 选择 **Advanced**（高级）。

1. 对于 **IAM 角色**，执行以下操作之一：
   + 如果 **aws-opsworks-service-role** 可用，选择该选项。
   + 如果**aws-opsworks-service-role**不可用，请选择**新建 IAM 角色**。

1. 对于 **Default IAM; 实例配置文件**，执行下列操作之一：
   + 如果有 **aws-opsworks-ec2 个角色**可用，请选择它。
   + 如果**aws-opsworks-ec双角色**不可用，请选择**新建 IAM 实例配置文件**。

1. 对以下项目保留默认值：
   + **Default root device type** (**EBS backed**)
   + **Hostname theme** (**Layer Dependent**)
   + **OpsWorks 代理版本**（最新版本）
   + **Custom Chef JSON** (空白)
   + **安全**，**使用 OpsWorks 安全组**（**是**）

1. 选择**添加堆栈**。 OpsWorks 堆栈创建堆栈并显示**MyCookbooksDemoStack**页面。

**创建层**

1. 在服务导航窗格中，选择 **Layers**。此时将显示 **Layers** 页面。

1. 选择 **Add a layer**。

1. 在**OpsWorks**选项卡上，在 “**名称**” 中键入**MyCookbooksDemoLayer**。您可以键入一个不同的名称，但务必在本演练过程中将其替换为 `MyCookbooksDemoLayer`。

1. 对于 **Short name (短名称)**，键入 **cookbooks-demo**。您可以键入一个不同的名称，但务必在本演练过程中将其替换为 `cookbooks-demo`。

1. 选择**添加图层**。 OpsWorks Stacks 添加图层并显示**图层**页面。

**创建并启动实例**

1. 在服务导航窗格中，选择 **Instances**。这将显示 **Instances** 页面。

1. 选择**添加一个实例**。

1. 在 **New** 选项卡上，选择 **Advanced**。

1. 对以下项目保留默认值：
   + **Hostname** (**cookbooks-demo1**)
   + **Size** (**c3.large**)
   + **子网**（*IP address***us-west-2** a）
   + **Scaling type** (**24/7**)
   + **SSH key** (**Do not use a default SSH key**)
   + **操作系统** （**Amazon Linux 2016.09**)
   + **OpsWorks 代理版本**（**继承自堆栈**）
   + **Tenancy** (**Default - Rely on VPC settings**)
   + **Root device type** (**EBS backed**)
   + **Volume type** (**General Purpose (SSD)**)
   + **Volume size** (**8**)

1. 选择 **Add instance**。

1. **对于 **MyCookbooksDemoLayer****cookbooks-demo1**，在 “**操作” 中，选择 “开始”**。**请在 **Status** 变为 **online** 之后继续。此过程可能需要几分钟的时间，请耐心等待。

您现在获得了一个堆栈、一个层以及一个实例 (系统会自动将说明书从您的 S3 存储桶复制到该实例)。在[下一步](gettingstarted-cookbooks-test-recipe.md)中，您将在实例上的说明书中运行并测试默认配方。

# 第 3 步：运行并测试配方
<a name="gettingstarted-cookbooks-test-recipe"></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 支持 团队联系。

从 OpsWorks Stacks 复制到实例的`default`食谱中运行并测试食谱。您可能还记得，这是一个一行配方，当配方运行时，将在日志中显示一条简单的消息。

**运行配方**

1. 在服务导航窗格中，选择 **Stack**。屏幕上随即显示 **MyCookbooksDemoStack** 页面。

1. 选择 **Run Command**。此时将显示 **Run Command** 页面。

1. 对于 **Command**，选择 **Execute Recipes**。

1. 对于 **Recipes to execute (要执行的配方)**，请键入 **opsworks\$1cookbook\$1demo::default**。

   **opsworks\$1cookbook\$1demo** 是 `metadata.rb` 文件中定义的说明书的名称。**default** 是要运行的配方的名称，也就是，说明书的 `recipes` 子目录中 `default.rb` 文件的名称，不带文件扩展名。

1. 保留以下默认设置：
   + **Comment** (空白)
   + **Advanced**，**Custom Chef JSON** (空白)
   + **实例**（**选择所有**已选中、已选中、**MyCookbooksDemoLayer**选中 **cookbooks-** demo1）

1. 选择 **Execute Recipes**。此时将显示 **Running command execute\$1recipes** 页面。请在 **Status** 变为 **successful** 之后继续。此过程可能需要几分钟的时间，请耐心等待。

**检查配方的结果**

1. 显示 **Running command execute\$1recipes** 页面时，对于 **cookbooks-demo1** 中的 **Log**，选择 **show**。此时将显示 **execute\$1recipes** 日志页面。

1. 向下滚动日志并查找类似于以下内容的条目：

   ```
   [2015-11-13T19:14:39+00:00] INFO: ********** Hello, World! **********
   ```

您已成功运行您的第一个配方！在[下一步](gettingstarted-cookbooks-install-package.md)中，您将通过添加一个可在实例上安装程序包的配方来更新您的说明书。

# 第 4 步：更新说明书以安装程序包
<a name="gettingstarted-cookbooks-install-package"></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 支持 团队联系。

通过添加可在实例上安装包含受欢迎的文本编辑器 GNU Emacs 的程序包的配方，更新您的说明书。

尽管你可以同样轻松地登录实例并安装一次软件包，但编写配方可以让你从 OpsWorks Stacks 运行一次配方，同时在堆栈中的多个实例上安装多个软件包。

**更新说明书以安装程序包**

1. 返回您的本地工作站，在 `opsworks_cookbook_demo` 目录的 `recipes` 子目录中，创建名为 `install_package.rb` 的包含以下代码的文件：

   ```
   package "Install Emacs" do
     package_name "emacs"
   end
   ```

   此配方将在实例上安装 `emacs` 程序包。(有关更多信息，请转到 [package](https://docs.chef.io/resource_package.html)。)
**注意**  
您可以将配方命名为您喜欢的任何文件名称。每当你想让 OpsWorks Stacks 运行食谱时，一定要指定正确的食谱名称即可。

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

当您更新实例上的说明书，然后从更新后的说明书中运行新配方时，这个新配方就会运行。下一步骤将介绍如何执行此操作。

完成[下一步](gettingstarted-cookbooks-copy-cookbook.md)后，您将能够登录实例，然后在命令提示符下键入 **emacs** 以启动 GNU Emacs。（有关更多信息，请参阅[连接到您的 Linux 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstances.html)。） 要退出 GNU Emacs，按 **Ctrl\$1X**，然后按 **Ctrl\$1C**。

**重要**  
要登录实例，您必须先向 OpsWorks Stacks 提供有关您的 SSH 公钥的信息（您可以使用 ssh-keygen 或 Pu 等工具创建该密钥TTYgen），然后您必须在`MyCookbooksDemoStack`堆栈上设置权限以允许您的用户登录实例。有关说明，请参阅[注册用户的公有 SSH 密钥](security-settingsshkey.md)和[使用 SSH 登录](workinginstances-ssh.md)。

# 第 5 步：更新实例上的说明书并运行配方
<a name="gettingstarted-cookbooks-copy-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 支持 团队联系。

更新实例上的说明书，然后从实例上的更新后的说明书中运行配方。在本演练的其余步骤中，您每次通过添加新的配方来更新说明书时，就需要重复此步骤。

**更新实例上的说明书**

1. 在服务导航窗格中，选择 **Stack**。屏幕上随即显示 **MyCookbooksDemoStack** 页面。

1. 选择 **Run Command**。此时将显示 **Run Command** 页面。

1. 对于 **Command**，选择 **Update Custom Cookbooks**。

1. 保留以下默认设置：
   + **Comment** (空白)
   + **Advanced**，**Custom Chef JSON** (空白)
   + **高级**，**实例**（**选择所有选中**、选中、**cookbooks-** demo1 **MyCookbooksDemoLayer**选中）

1. 选择 **Update Custom Cookbooks**。此时将显示 **Running command update\$1custom\$1cookbooks** 页面。请在 **Status** 变为 **successful** 之后继续。此过程可能需要几分钟的时间，请耐心等待。

**运行配方**

1. 在服务导航窗格中，选择 **Stack**。屏幕上随即显示 **MyCookbooksDemoStack** 页面。

1. 选择 **Run Command**。此时将显示 **Run Command** 页面。

1. 对于 **Command**，选择 **Execute Recipes**。

1. 对于 **Recipes to execute**，键入要运行的配方的名称。当您第一次执行此操作时，配方名称为 **opsworks\$1cookbook\$1demo::install\$1package**。
**注意**  
稍后当您重复此步骤时，键入说明书的名称 (**opsworks\$1cookbook\$1demo**)，后面键入两个冒号 (**::**)，这两个冒号后面再键入配方的名称（配方的文件名，不带 `.rb` 文件扩展名）。

1. 保留以下默认设置：
   + **Comment** (空白)
   + **Advanced**，**Custom Chef JSON** (空白)
   + **实例****选择所有选中**、**MyCookbooksDemoLayer**选中、**cookbooks-** demo1 选中）

1. 选择 **Execute Recipes**。此时将显示 **Running command execute\$1recipes** 页面。请在 **Status** 变为 **successful** 之后继续。此过程可能需要几分钟的时间，请耐心等待。

**注意**  
您无需手动运行配方。您可以将配方分配给图层的生命周期事件，例如设置和配置事件，当事件发生时， OpsWorks Stacks 将自动运行这些配方。有关更多信息，请参阅 [OpsWorks 堆栈生命周期事件](workingcookbook-events.md)。

在[下一步](gettingstarted-cookbooks-add-user.md)中，您将更新说明书以将用户添加到实例。

# 第 6 步：更新说明书以添加用户
<a name="gettingstarted-cookbooks-add-user"></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 支持 团队联系。

通过添加可将本地用户添加到实例并设置该用户的主目录和 Shell 的配方，来更新您的说明书。这与运行 Linux **adduser** 或 **useradd** 命令或者 Windows **net user** 命令相似。您可以将一个本地用户添加到实例，例如，当您想要控制对该实例的文件和目录的访问时。

您也可以在不使用说明书的情况下管理用户。有关更多信息，请参阅 [管理用户](opsworks-security-users-manage.md)。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `opsworks_cookbook_demo` 目录的 `recipes` 子目录中，创建名为 `add_user.rb` 的包含以下代码的文件 (有关更多信息，请转到[用户](https://docs.chef.io/resource_user.html))：

   ```
   user "Add a user" do
     home "/home/jdoe"
     shell "/bin/bash"
     username "jdoe"  
   end
   ```

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::add\$1user**。

**测试配方**

1. 如果您尚未登录实例，请登录。

1. 在命令提示符下，运行以下命令以确认已添加新用户：

   ```
   grep jdoe /etc/passwd
   ```

   此时将显示以下用户信息，包括用户的名称、ID 号、组 ID 号、主目录和 Shell 等详细信息：

   ```
   jdoe:x:501:502::/home/jdoe:/bin/bash
   ```

在[下一步](gettingstarted-cookbooks-create-directory.md)中，您将更新说明书以在实例上创建一个目录。

# 第 7 步：更新说明书以创建目录
<a name="gettingstarted-cookbooks-create-directory"></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 支持 团队联系。

通过添加可向实例添加目录的配方，更新您的说明书。这与运行 Linux **mkdir** 命令或者 Windows **md** 或 **mkdir** 命令相似。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `opsworks_cookbook_demo` 目录的 `recipes` 子目录中，创建名为 `create_directory.rb` 的包含以下代码的文件。有关更多信息，请转至 [directory](https://docs.chef.io/resource_directory.html)：

   ```
   directory "Create a directory" do
     group "root"
     mode "0755"
     owner "ec2-user"
     path "/tmp/create-directory-demo"  
   end
   ```

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::create\$1directory**。

**测试配方**

1. 如果您尚未登录实例，请登录。

1. 在命令提示符下，运行以下命令以确认已添加新目录：

   ```
   ls -la /tmp/create-directory-demo
   ```

   此时将显示新添加目录的相关信息，包括许可、所有者名称和组名称等信息：

   ```
   drwxr-xr-x 2 ec2-user root 4096 Nov 18 00:35 .
   drwxrwxrwt 6 root     root 4096 Nov 24 18:17 ..
   ```

在[下一步](gettingstarted-cookbooks-create-file.md)中，您将更新说明书以在实例上创建一个文件。

# 第 8 步：更新说明书以创建并复制文件
<a name="gettingstarted-cookbooks-create-file"></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 支持 团队联系。

通过添加可向实例添加两个文件的配方，更新您的说明书。配方中的第一个资源创建一个全部内容都是配方代码的文件。这与运行 Linux **cat**、**echo** 或 **touch** 命令或者 Windows **echo** 或 **fsutil** 命令相似。此方法适用于文件数量少、文件小或简单的情况。配方中第二个资源将说明书中的一个文件复制到实例上的另一个目录中。这与运行 Linux **cp** 命令或 Windows **copy** 命令相似。此方法适用于文件数量多、文件大或复杂的情况。

在开始执行此步骤之前，请完成[第 7 步：更新说明书以创建目录](gettingstarted-cookbooks-create-directory.md)，以确保文件的父目录已经存在。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `opsworks_cookbook_demo` 目录中，创建名为 `files` 的目录。

1. 在 `files` 子目录中，创建一个名为 `hello.txt` 的文件，该文件包含以下文本：**Hello, World\$1**

1. 在 `opsworks_cookbook_demo` 目录的 `recipes` 子目录中，创建名为 `create_files.rb` 的包含以下代码的文件。有关更多信息，请转至 [file](https://docs.chef.io/resource_file.html) 和 [cookbook\$1file](https://docs.chef.io/resource_cookbook_file.html)。

   ```
   file "Create a file" do
     content "<html>This is a placeholder for the home page.</html>"
     group "root"
     mode "0755"
     owner "ec2-user"
     path "/tmp/create-directory-demo/index.html"
   end
   
   cookbook_file "Copy a file" do  
     group "root"
     mode "0755"
     owner "ec2-user"
     path "/tmp/create-directory-demo/hello.txt"
     source "hello.txt"  
   end
   ```

   `file` 资源可在指定路径中创建文件。`cookbook_file` 资源将您刚刚在说明书中创建的 `files` 目录中的文件 (Chef 预计会找到一个可以复制其中文件的、名为 `files` 的标准命名的子目录) 复制到实例的另一个目录中。

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::create\$1files**。

**测试配方**

1. 如果您尚未登录实例，请登录。

1. 在命令提示符下，运行以下命令 (一次运行一个命令)，以确认已添加新文件：

   ```
   sudo cat /tmp/create-directory-demo/index.html
   
   sudo cat /tmp/create-directory-demo/hello.txt
   ```

   随即将显示该文件的内容：

   ```
   <html>This is a placeholder for the home page.</html>
   
   Hello, World!
   ```

在[下一步](gettingstarted-cookbooks-run-command.md)中，您将更新说明书以在实例上运行一个命令。

# 第 9 步：更新说明书以运行命令
<a name="gettingstarted-cookbooks-run-command"></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 支持 团队联系。

通过添加可运行用于在实例上创建 SSH 秘钥的命令的配方，更新您的说明书。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `opsworks_cookbook_demo` 目录的 `recipes` 子目录中，创建名为 `run_command.rb` 的包含以下代码的文件。有关更多信息，请转到 [execute](https://docs.chef.io/resource_execute.html)。

   ```
   execute "Create an SSH key" do
     command "ssh-keygen -f /tmp/my-key -N fLyC3jbY"
   end
   ```

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::run\$1command**。

**测试配方**

1. 如果您尚未登录实例，请登录。

1. 在命令提示符下，运行以下命令 (一次运行一个命令)，以确认已创建 SSH 密钥：

   ```
   sudo cat /tmp/my-key
   
   sudo cat /tmp/my-key.pub
   ```

   随即显示 SSH 私有和公有密钥的内容：

   ```
   -----BEGIN RSA PRIVATE KEY-----
   Proc-Type: 4,ENCRYPTED
   DEK-Info: AES-128-CBC,DEF7A09C...541583FA
   A5p9dCuo...wp0YYH1c
   -----END RSA PRIVATE KEY-----
   
   ssh-rsa AAAAB3N...KaNogZkT root@cookbooks-demo1
   ```

在[下一步](gettingstarted-cookbooks-run-script.md)中，您将更新说明书以在实例上运行一个脚本。

# 第 10 步：更新说明书以运行脚本
<a name="gettingstarted-cookbooks-run-script"></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 支持 团队联系。

通过添加可在实例上运行脚本的配方来更新您的说明书。此配方会创建一个目录，然后在该目录中创建一个文件。编写一个配方以运行包含多个命令的脚本，比一次运行其中一个命令简单。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `opsworks_cookbook_demo` 目录的 `recipes` 子目录中，创建名为 `run_script.rb` 的包含以下代码的文件。有关更多信息，请转到 [script](https://docs.chef.io/resource_script.html)。

   ```
   script "Run a script" do
     interpreter "bash"
     code <<-EOH
       mkdir -m 777 /tmp/run-script-demo
       touch /tmp/run-script-demo/helloworld.txt
       echo "Hello, World!" > /tmp/run-script-demo/helloworld.txt
     EOH
   end
   ```

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::run\$1script**。

**测试配方**

1. 如果您尚未登录实例，请登录。

1. 在命令提示符下，运行以下命令以确认已添加新文件：

   ```
   sudo cat /tmp/run-script-demo/helloworld.txt
   ```

   随即将显示该文件的内容：

   ```
   Hello, World!
   ```

在[下一步](gettingstarted-cookbooks-manage-service.md)中，您将更新说明书以管理实例上的服务。

# 第 11 步：更新说明书以管理服务
<a name="gettingstarted-cookbooks-manage-service"></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 支持 团队联系。

通过在实例上添加可管理服务的配方来更新您的说明书。这与运行 Linux **service** 命令或者 Windows **net stop**、**net start** 和类似命令相似。此配方会停止实例上的 **crond** 服务。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `opsworks_cookbook_demo` 目录的 `recipes` 子目录中，创建名为 `manage_service.rb` 的包含以下代码的文件。有关更多信息，请转到 [service](https://docs.chef.io/resource_service.html)。

   ```
   service "Manage a service" do
     action :stop
     service_name "crond"  
   end
   ```

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::manage\$1service**。

**测试配方**

1. 如果您尚未登录实例，请登录。

1. 在命令提示符下，运行以下命令以确认 **crond** 服务已停止：

   ```
   service crond status
   ```

   随即将显示以下内容：

   ```
   crond is stopped
   ```

1. 要重新启动 **crond** 服务，运行以下命令：

   ```
   sudo service crond start
   ```

   随即将显示以下内容：

   ```
   Starting crond:  [  OK  ]
   ```

1.  要确认 **crond** 服务已启动，再次运行以下命令：

   ```
   service crond status
   ```

   随即将显示如下信息：

   ```
   crond (pid  3917) is running...
   ```

在[下一步](gettingstarted-cookbooks-custom-json.md)中，您将更新说明书，以引用以自定义 JSON 形式存储于实例上的信息。

# 第 12 步：更新说明书以使用自定义 JSON
<a name="gettingstarted-cookbooks-custom-json"></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 支持 团队联系。

通过添加可引用存储于实例上的自定义 JSON 的配方，更新您的说明书。

当您创建、更新或克隆堆栈时，或者当您运行部署或堆栈命令时，您可以以自定义的 JSON 格式指定信息。例如，这对为实例上您的配方提供小部分不变数据来代替从数据库中获得此数据来说非常有用。有关更多信息，请参阅 [使用自定义 JSON](workingstacks-json.md)。

在本演练中，您将使用自定义 JSON 来提供关于客户发票的一些虚构信息。本步骤后面部分将对自定义 JSON 进行讲解。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `recipes` 目录的 `opsworks_cookbook_demo` 子目录中，创建名为 `custom_json.rb` 的包含以下配方代码的文件：

   ```
   Chef::Log.info("********** For customer '#{node['customer-id']}' invoice '#{node['invoice-number']}' **********")
   Chef::Log.info("********** Invoice line number 1 is a '#{node['line-items']['line-1']}' **********")
   Chef::Log.info("********** Invoice line number 2 is a '#{node['line-items']['line-2']}' **********")
   Chef::Log.info("********** Invoice line number 3 is a '#{node['line-items']['line-3']}' **********")
   ```

   此配方显示日志中关于自定义 JSON 中的值的消息。

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::custom\$1json**。对于 **Advanced**、**Custom Chef JSON**，键入以下自定义 JSON：

   ```
   {
     "customer-id": "0123",
     "invoice-number": "9876",
     "line-items": {
       "line-1": "tractor",
       "line-2": "passenger car",
       "line-3": "trailer"
     }
   }
   ```

**测试配方**

1. 通过上一步骤显示了 **Running command execute\$1recipes** 页面时，对于 **cookbooks-demo1** 中的 **Log**，选择 **show**。此时将显示 **execute\$1recipes** 日志页面。

1. 向下滚动日志以查找类似于以下内容的条目：

   ```
   [2015-11-14T14:18:30+00:00] INFO: ********** For customer '0123' invoice '9876' **********
   [2015-11-14T14:18:30+00:00] INFO: ********** Invoice line number 1 is a 'tractor' **********
   [2015-11-14T14:18:30+00:00] INFO: ********** Invoice line number 2 is a 'passenger car' **********
   [2015-11-14T14:18:30+00:00] INFO: ********** Invoice line number 3 is a 'trailer' **********
   ```

   这些条目显示在 **Advanced**、**Custom Chef JSON** 框中键入的自定义 JSON 的信息。

在[下一步](gettingstarted-cookbooks-data-bags.md)中，您将更新食谱以从数据袋中获取信息，数据袋是 Stac OpsWorks ks 在每个实例上存储的堆栈设置的集合。

# 第 13 步：更新说明书以使用数据包
<a name="gettingstarted-cookbooks-data-bags"></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 支持 团队联系。

通过添加一个引用 Stac OpsWorks ks 存储在实例上的堆栈设置的食谱来更新你的食谱，这些设置存储在一组数据袋中。此配方会在日志中显示存储在实例上的具体堆栈设置的消息。有关更多信息，请参阅[OpsWorks 堆栈数据包参考](data-bags.md)。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `recipes` 目录的 `opsworks_cookbook_demo` 子目录中，创建名为 `data_bags.rb` 的包含以下代码的文件：

   ```
   instance = search("aws_opsworks_instance").first
   layer = search("aws_opsworks_layer").first
   stack = search("aws_opsworks_stack").first
   
   Chef::Log.info("********** This instance's instance ID is '#{instance['instance_id']}' **********")
   Chef::Log.info("********** This instance's public IP address is '#{instance['public_ip']}' **********")
   Chef::Log.info("********** This instance belongs to the layer '#{layer['name']}' **********")
   Chef::Log.info("********** This instance belongs to the stack '#{stack['name']}' **********")
   Chef::Log.info("********** This stack gets its cookbooks from '#{stack['custom_cookbooks_source']['url']}' **********")
   ```

   此配方会在日志中显示存储在实例上的具体堆栈设置的消息。

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::data\$1bags**。

**测试配方**

1. 通过上一步骤显示了 **Running command execute\$1recipes** 页面时，对于 **cookbooks-demo1** 中的 **Log**，选择 **show**。此时将显示 **execute\$1recipes** 日志页面。

1. 向下滚动日志并查找类似于以下内容的条目：

   ```
   [2015-11-14T14:39:06+00:00] INFO: ********** This instance's instance ID is 'f80fa119-81ab-4c3c-883d-6028e52c89EX' **********
   [2015-11-14T14:39:06+00:00] INFO: ********** This instance's public IP address is '192.0.2.0' **********
   [2015-11-14T14:39:06+00:00] INFO: ********** This instance belongs to the layer 'MyCookbooksDemoLayer' **********
   [2015-11-14T14:39:06+00:00] INFO: ********** This instance belongs to the stack 'MyCookbooksDemoStack' **********
   [2015-11-14T14:39:06+00:00] INFO: ********** This stack gets its cookbooks from 'https://s3.amazonaws.com/amzn-s3-demo-bucket/opsworks_cookbook_demo.tar.gz' **********
   ```

   此配方会显示存储在实例上的具体堆栈设置的消息。

在[下一步](gettingstarted-cookbooks-iteration.md)中，您将更新说明书以多次运行配方代码。

# 第 14 步：更新说明书以使用迭代
<a name="gettingstarted-cookbooks-iteration"></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 支持 团队联系。

通过添加可使用*迭代* (一种多次重复配方代码的方法) 的配方，更新您的说明书。此配方会在日志中显示包含多方面内容的数据包项目的消息。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `recipes` 目录的 `opsworks_cookbook_demo` 子目录中，创建名为 `iteration_demo.rb` 的包含以下代码的文件：

   ```
   stack = search("aws_opsworks_stack").first
   Chef::Log.info("********** Content of 'custom_cookbooks_source' **********")
   
   stack["custom_cookbooks_source"].each do |content|
     Chef::Log.info("********** '#{content}' **********")
   end
   ```
**注意**  
编写上述配方代码比编写下面未使用迭代的配方代码用时更短、更灵活，且较不容易出错。  

   ```
   stack = search("aws_opsworks_stack").first
   Chef::Log.info("********** Content of 'custom_cookbooks_source' **********")
   
   Chef::Log::info("********** '[\"type\", \"#{stack['custom_cookbooks_source']['type']}\"]' **********")
   Chef::Log::info("********** '[\"url\", \"#{stack['custom_cookbooks_source']['url']}\"]' **********")
   Chef::Log::info("********** '[\"username\", \"#{stack['custom_cookbooks_source']['username']}\"]' **********")
   Chef::Log::info("********** '[\"password\", \"#{stack['custom_cookbooks_source']['password']}\"]' **********")
   Chef::Log::info("********** '[\"ssh_key\", \"#{stack['custom_cookbooks_source']['ssh_key']}\"]' **********")
   Chef::Log::info("********** '[\"revision\", \"#{stack['custom_cookbooks_source']['revision']}\"]' **********")
   ```

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::iteration\$1demo**。

**测试配方**

1. 通过上一步骤显示了 **Running command execute\$1recipes** 页面时，对于 **cookbooks-demo1** 中的 **Log**，选择 **show**。此时将显示 **execute\$1recipes** 日志页面。

1. 向下滚动日志并查找类似于以下内容的条目：

   ```
   [2015-11-16T19:56:56+00:00] INFO: ********** Content of 'custom_cookbooks_source' **********
   [2015-11-16T19:56:56+00:00] INFO: ********** '["type", "s3"]' **********
   [2015-11-16T19:56:56+00:00] INFO: ********** '["url", "https://s3.amazonaws.com/amzn-s3-demo-bucket/opsworks_cookbook_demo.tar.gz"]' **********
   [2015-11-16T19:56:56+00:00] INFO: ********** '["username", "secret-key-value"]' **********
   [2015-11-16T19:56:56+00:00] INFO: ********** '["password", "secret-access-key-value"]' **********
   [2015-11-16T19:56:56+00:00] INFO: ********** '["ssh_key", nil]' **********
   [2015-11-16T19:56:56+00:00] INFO: ********** '["revision", nil]' **********
   ```

   此配方会在日志中显示包含多方面内容的数据包项目的消息。数据包项目位于 `aws_opsworks_stack` 数据包中。数据包项目包含名为 `custom_cookbooks_source` 的内容。此内容包含六个部分，名称分别为 `type`、`url`、`username`、`password`、`ssh_key` 和 `revision`；还会显示它们的值。

在[下一步](gettingstarted-cookbooks-conditional-logic.md)中，您将更新说明书以仅在满足了某些条件后才运行配方代码。

# 第 15 步：更新说明书以使用条件逻辑
<a name="gettingstarted-cookbooks-conditional-logic"></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 支持 团队联系。

现在，通过添加可使用*条件逻辑* (只有在满足某些条件时才运行代码的一种方法) 的配方来更新您的说明书。有关更多信息，请转到 [if Statements](https://docs.chef.io/dsl_recipe.html#if-statements) 和 [case Statements](https://docs.chef.io/dsl_recipe.html#case-statements)。

此配方会根据数据包内容执行两项操作：在日志中显示一则消息以确定实例在哪个操作系统上运行，以及只有在操作系统是 Linux 的情况下，才会为所规定的 Linux 发行版使用相应的程序包管理器来安装程序包。此程序包名为“tree”，是一款用于显示目录列表的简单应用程序。

**更新实例上的说明书并运行新的配方**

1. 在您的本地工作站上的 `opsworks_cookbook_demo directory` 的 `recipes` 子目录中，创建名为 `conditional_logic.rb` 的包含以下代码的文件：

   ```
   instance = search("aws_opsworks_instance").first
   os = instance["os"]
   
   if os == "Red Hat Enterprise Linux 7"
     Chef::Log.info("********** Operating system is Red Hat Enterprise Linux. **********")
   elsif os == "Ubuntu 14.04 LTS" || os == "Ubuntu 16.04 LTS" || os == "Ubuntu 18.04 LTS"
     Chef::Log.info("********** Operating system is Ubuntu. **********") 
   elsif os == "Microsoft Windows Server 2012 R2 Base"
     Chef::Log.info("********** Operating system is Windows. **********")
   elsif os == "Amazon Linux 2015.03" || os == "Amazon Linux 2015.09" || os == "Amazon Linux 2016.03" || os == "Amazon Linux 2016.09" || os == "Amazon Linux 2017.03" || os == "Amazon Linux 2017.09" || os == "Amazon Linux 2018.03" || os == "Amazon Linux 2"
     Chef::Log.info("********** Operating system is Amazon Linux. **********")
   elsif os == "CentOS Linux 7"
     Chef::Log.info("********** Operating system is CentOS 7. **********")
   else
     Chef::Log.info("********** Cannot determine operating system. **********")
   end
   
   case os
   when "Ubuntu 14.04 LTS", "Ubuntu 16.04 LTS", "Ubuntu 18.04 LTS"
     apt_package "Install a package with apt-get" do
       package_name "tree"
     end
   when "Amazon Linux 2015.03", "Amazon Linux 2015.09", "Amazon Linux 2016.03", "Amazon Linux 2016.09", "Amazon Linux 2017.03", "Amazon Linux 2017.09", "Amazon Linux 2018.03", "Amazon Linux 2", "Red Hat Enterprise Linux 7", "CentOS Linux 7"
     yum_package "Install a package with yum" do
       package_name "tree"
     end
   else
     Chef::Log.info("********** Cannot determine operating system type, or operating system is not Linux. Package not installed. **********")
   end
   ```

1. 在终端处或在命令提示符下，使用 **tar** 命令创建 `opsworks_cookbook_demo.tar.gz` 文件的新版本，该文件包含 `opsworks_cookbook_demo` 目录及其更新的内容。

1. 将更新后的 `opsworks_cookbook_demo.tar.gz` 文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::conditional\$1logic**。

**测试配方**

1. 通过上一步骤显示了 **Running command execute\$1recipes** 页面时，对于 **cookbooks-demo1** 中的 **Log**，选择 **show**。此时将显示 **execute\$1recipes** 日志页面。

1. 向下滚动日志并查找类似于以下内容的条目：

   ```
   [2015-11-16T19:59:05+00:00] INFO: ********** Operating system is Amazon Linux. **********
   ```

   由于实例的操作系统是 Amazon Linux 2016.09，日志中将仅显示 (配方代码中五个可能的条目的) 前一个条目。

1. 如果操作系统是 Linux，配方会安装树包。要查看形象化的目录内容，在预期目录的命令提示符下键入 **tree** 或键入预期目录的路径（例如 `tree /var/chef/runs`）。

在[下一步](gettingstarted-cookbooks-community-cookbooks.md)中，您将更新说明书，以使用由 Chef 社区提供的外部说明书的功能。

# 第 16 步：更新说明书以使用社区说明书
<a name="gettingstarted-cookbooks-community-cookbooks"></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 支持 团队联系。

最后，更新说明书以使用 Chef 社区提供的外部说明书中的功能。您用于此演练的外部说明书，可以通过 [Chef Supermarket](https://supermarket.chef.io/) (访问外部 Chef 说明书的一个普通地方) 获得。此外部说明书提供自定义资源，利用这个资源，您可以下载和安装应用程序，这类似于您在[第 4 步：更新说明书以安装程序包](gettingstarted-cookbooks-install-package.md)中执行的操作。不过，此资源除了可以安装程序包以外，还可以 Web 应用程序和其他类型的应用程序。

当一个说明书依赖另一个说明书时，您必须指定对另一个说明书的依赖项。要宣布和管理说明书依赖项，我们建议您使用一个名为 Berkshelf 的工具。有关如何在本地工作站上安装 Berkshelf 的更多信息，请参阅 Chef 网站上的[关于 Berkshelf](https://docs.chef.io/berkshelf.html)。

当您安装 Berkshelf 后，按照以下步骤来宣布说明书依赖项，然后创建可在外部说明书中调用资源的配方：

**宣布说明书依赖项**

1. 在您的本地工作站上的 `opsworks_cookbook_demo` 目录中，在 `metadata.rb` 文件的结尾添加以下行：

   ```
   depends "application", "5.0.0"
   ```

   这可宣布对一个名为 `application` 的说明书 (版本 5.0.0.) 的依赖项。

1. 从 `opsworks_cookbook_demo` 目录的根目录运行以下命令。命令末尾的句点是有意设计的。

   ```
   berks init .
   ```

   Berkshelf 创建的许多文件夹和文件都可以用于以后更高级的方案。对于此演练，我们需要的唯一文件是名为 `Berksfile` 的文件。

1. 将以下行添加到 `Berksfile` 文件的末尾处：

   ```
   cookbook "application", "5.0.0"
   ```

   这将告知 Berkshelf，您要使用 Berkshelf 从 Chef Supermarket 下载的[应用程序说明书版本 5.0.0](https://supermarket.chef.io/cookbooks/application/versions/5.0.0)。

1. 在终端处或在命令提示符下，在 `opsworks_cookbook_demo` 目录的根目录下运行以下命令：

   ```
   berks install
   ```

   Berkshelf 将创建一份您的说明书以及应用程序说明书的依赖项列表。Berkshelf 在下一个步骤中使用此依赖项列表。

**更新实例上的说明书并运行新的配方**

1. 在 `recipes` 目录的 `opsworks_cookbook_demo` 子目录中，创建名为 `dependencies_demo.rb` 的包含以下代码的文件：

   ```
   application "Install NetHack" do
     package "nethack.x86_64"
   end
   ```

   此方法依赖于应用程序食谱中的应用程序资源，以便在实例 NetHack 上安装流行的基于文本的冒险游戏。(当然，您可以替换想要替换的其他任何程序包名称，但前提是实例上程序包管理器要能够随时获得程序包。)

1. 从 `opsworks_cookbook_demo` 目录的根目录运行以下命令：

   ```
   berks package
   ```

   Berkshelf 使用上一个步骤中创建的依赖项列表创建一个名为 `cookbooks-timestamp.tar.gz` 的文件，该文件包含 `opsworks_cookbook_demo` 目录和其更新后的内容 (包括说明书所依赖的说明书)。将此文件重命名为 `opsworks_cookbook_demo.tar.gz`。

1. 将更新后重命名为 `opsworks_cookbook_demo.tar.gz` 的文件上传到 S3 存储桶。

1. 按照[第 5 步：更新实例上的说明书并运行配方](gettingstarted-cookbooks-copy-cookbook.md)中的步骤，更新实例上的说明书并运行配方。在“运行配方”步骤中，对于 **Recipes to execute (要执行的配方)**，键入 **opsworks\$1cookbook\$1demo::dependencies\$1demo**。

1. 运行配方后，您应当能够登录实例，然后在命令提示符下键入 **nethack** 以开始播放。（有关游戏的更多信息，请参阅[NetHack](https://en.wikipedia.org/wiki/NetHack)和[NetHack指南](http://www.nethack.org/v343/Guidebook.html)。） 

在[下一步](gettingstarted-cookbooks-clean-up.md)中，您可以清理用于本演练的 AWS 资源。下一步是可选的。随着您继续了解 OpsWorks Stacks的更多信息，您可能需要继续使用这些 AWS 资源。但是，保留这些 AWS 资源可能会导致您的 AWS 账户持续收取一些费用。如果你想保留这些 AWS 资源以备后用，现在你已经完成了本演练，你可以直接跳到[后续步骤](gettingstarted-cookbooks-next-steps.md)。

# 步骤 17：(可选) 清除
<a name="gettingstarted-cookbooks-clean-up"></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 支持 团队联系。

为防止您的 AWS 账户产生额外费用，您可以删除用于本演练的 AWS 资源。这些 AWS 资源包括 S3 存储桶、堆栈 OpsWorks 堆栈和堆栈的组件。（有关更多信息，请参阅 [AWS OpsWorks 定价](https://aws.amazon.com/opsworks/pricing/)。） 但是，随着您继续了解 OpsWorks Stacks的更多信息，您可能需要继续使用这些 AWS 资源。如果你想让这些 AWS 资源保持可用，现在你已经完成了本演练，你可以跳到[后续步骤](gettingstarted-cookbooks-next-steps.md)。

为本演练创建的资源中存储的内容可以包含个人可识别信息。如果您不再希望由 AWS存储此信息，请执行本主题中的步骤。

**删除 S3 存储桶**
+ 请参阅[删除 Amazon S3 存储桶](https://docs.aws.amazon.com/gettingstarted/latest/swh/getting-started-cleanup-s3.html)。

**删除堆栈的实例**

1. 在 OpsWorks 堆栈控制台的服务导航窗格中，选择**实例**。这将显示 **Instances** 页面。

1. **对于 **MyCookbooksDemoLayer****cookbooks-demo1**，在 “**操作” 中，选择 “停止”**。**看到确认消息后，选择 **Stop**。

1. 以下更改需要几分钟的时间才能生效。请等待以下所有操作均完成后再继续。
   + **Status** 从 **online** 变为 **stopping**，最终变为 **stopped**。
   + **online** 从 **1** 变为 **0**。
   + **shutting down** 从 **0** 变为 **1**，最终变为 **0**。
   + **stopped** 最终从 **0** 变为 **1**。

1. 对于 **Actions**，选择 **delete**。当您看到确认消息时，选择**删除**。 OpsWorks Stacks 会删除实例并显示 “**无实例**”。

**删除堆栈**

1. 在服务导航窗格中，选择 **Stack**。屏幕上随即显示 **MyCookbooksDemoStack** 页面。

1. 选择 **Delete Stack**。当您看到确认消息时，选择**删除**。 OpsWorks Stacks 会删除堆栈并显示**控制面板**页面。

或者，如果您不想重复使用在本演练中使用的 IAM 用户和 Amazon ke EC2 y pair 访问其他 AWS 服务和 EC2实例，则可以将其删除。有关说明，请参阅[删除 IAM 用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_manage.html#id_users_deleting)和[亚马逊 EC2 密钥对以及 Linux 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html#delete-key-pair)。

现在，您已完成本演练。有关更多信息，请参阅 [后续步骤](gettingstarted-cookbooks-next-steps.md)。

# 后续步骤
<a name="gettingstarted-cookbooks-next-steps"></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 支持 团队联系。

现在你已经完成了本演练，你可以通过查看以下资源来详细了解 OpsWorks Stacks 对 Chef 食谱的支持：
+ [说明书和诀窍](workingcookbook.md)— 描述 OpsWorks Stacks 目前支持的 Chef 和 Ruby 版本。此外，还演示如何在实例上安装和更新自定义说明书，以及如何在实例上运行配方。
+ [Learn Chef](https://learn.chef.io/) – 提供 Chef 教程、Chef 技能库、完整 Chef 文档和 Chef 培训课程的链接。
+ [All about Chef](https://docs.chef.io/) – 提供完整的 Chef 文档。相关特定主题包括：
  + [About Cookbooks](https://docs.chef.io/cookbooks.html) – 介绍主要说明书组件，如属性、配方、文件、元数据和模板。
  + [About Recipes](https://docs.chef.io/recipes.html) – 介绍配方的基础知识，例如，如何使用数据包、如何包括其他配方以及如何在配方中使用 Ruby 代码。
  + [Resources](https://docs.chef.io/resources.html#resources) – 介绍如何使用所有内置 Chef 资源，如 `apt_package`、`cookbook_file`、`directory`、`execute`、`file` 和 `package`。
  + [About the Recipe DSL](https://docs.chef.io/dsl_recipe.html) – 介绍如何使用语句 (如 `if`、`case`、`data_bag`、`data_bag_item` 和 `search`) 为 Chef 配方编写代码。
+ [About Templates](https://docs.chef.io/templates.html) – 介绍如何使用 Embedded Ruby (ERB) 模板不断生成静态文本文件，如配置文件。
+ [Learning Tracks](https://learn.chef.io/tracks) – 介绍如何使用 Chef 管理实例、管理基本的 Web 应用程序、开发和测试基础设施代码、使用 Chef 分析等等。
+ [http://shop.oreilly.com/product/0636920032397.do](http://shop.oreilly.com/product/0636920032397.do) – Chef 简介。由 O'Reilly Media 出版。
+ [Learning Chef code examples](https://github.com/learningchef/learningchef-code) – 提供随附于由 O'Reilly Media 出版的书籍 *Learning Chef* 的代码示例。