

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

# 步骤 2.5：部署应用程序
<a name="gettingstarted-windows-deploy"></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 支持 团队联系。

IIS 安装将为应用程序的代码和相关文件创建一个 `C:\inetpub\wwwroot` 目录。下一步是将应用程序安装在此目录中。在本示例中，您将在 `default.html`中安装静态 HTML 主页 `C:\inetpub\wwwroot`。您可轻松扩展常规方法以处理更复杂的方案，如 ASP.NET 应用程序。

您可在您的说明书中包含应用程序的文件并让 `install.rb` 将这些文件复制到 `C:\inetpub\wwwroot`。有关如何执行此操作的示例，请参阅[示例 6：创建文件](cookbooks-101-basics-files.md)。但是，这种方法不是很灵活或高效，通常更好的方法是将说明书开发与应用程序开发分隔开。

首选解决方案是实施从存储库 (任何你喜欢的资源库，而不仅仅是说明书存储库) 检索应用程序的代码和相关文件的单独部署配方，并将此配方安装在每个 IIS 服务器实例上。此方法将说明书开发与应用程序开发分隔开，当您需要更新应用程序时，它允许您仅运行部署配方，而不必更新说明书。

本主题演示如何实施将 `default.htm` 部署到 IIS 服务器的简单部署配方。您可随时将此示例扩展到更复杂的应用程序。

**Topics**
+ [创建应用程序并将它存储在存储库中](#w2ab1c14c47c17c23c25c15)
+ [实施配方以部署应用程序](#w2ab1c14c47c17c23c25c17)
+ [更新实例的说明书](#w2ab1c14c47c17c23c25c19)
+ [将配方添加到自定义 IIS 层](#w2ab1c14c47c17c23c25c21)
+ [添加应用程序](#w2ab1c14c47c17c23c25c23)
+ [部署应用程序和打开应用程序](#w2ab1c14c47c17c23c25c25)

## 创建应用程序并将它存储在存储库中
<a name="w2ab1c14c47c17c23c25c15"></a>

您可对应用程序使用您更喜欢的任何存储库。为简便起见，此示例将 `default.htm` 存储在公有 S3 存储桶中。

**创建应用程序**

1. 在您的工作站上的方便位置创建一个名为 `iis-application` 的目录。

1. 将包含以下内容的 `default.htm` 文件添加到 `iis-application`。

   ```
   <!DOCTYPE html>
   <html>
     <head>
       <title>IIS Example</title>
     </head>
     <body>
       <h1>Hello World!</h1>
     </body>
   </html>
   ```

1. [创建 S3 存储桶](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)，[将 `default.htm` 上传到此存储桶](https://docs.aws.amazon.com/AmazonS3/latest/gsg/PuttingAnObjectInABucket.html)，并记录此 URL 供以后使用。为简单起见，请[将此文件设置为公用](https://docs.aws.amazon.com/AmazonS3/latest/gsg/OpeningAnObject.html)。
**注意**  
这是一个非常简单的应用程序，但您可扩展基本准则以处理生产级应用程序。  
对于具有多个文件的更复杂的应用程序，为 `iis-application` 创建 .zip 存档并将其上传至您的 S3 存储桶通常会更简单。  
随后，您可下载此 .zip 文件并将其内容提取到相应目录。无需下载多个文件，创建一个目录结构等。
对于生产应用程序，您可能希望保持您的文件私有。有关如何让配方从私有 S3 存储桶下载文件的示例，请参阅[在 OpsWorks Stacks Windows 实例上使用适用于 Ruby 的 SDK](cookbooks-101-opsworks-s3-windows.md)。
您可将应用程序存储在任何适当的存储库中。  
通常，您使用存储库的公用 API 下载应用程序。此示例使用 Amazon S3 API。例如，如果您在上存储应用程序 GitHub，则可以使用 [GitHub API](https://developer.github.com/guides/getting-started/)。

## 实施配方以部署应用程序
<a name="w2ab1c14c47c17c23c25c17"></a>

将名为 `deploy.rb` 的包含以下内容的配方添加到 `iis-cookbook` `recipes` 目录。

```
chef_gem "aws-sdk-s3" do
  compile_time false
  action :install
end

ruby_block "download-object" do
  block do
    require 'aws-sdk-s3'

    #1  
    # Aws.config[:ssl_ca_bundle] = 'C:\ProgramData\Git\bin\curl-ca-bundle.crt'
    Aws.use_bundled_cert!

    #2  
    query = Chef::Search::Query.new
    app = query.search(:aws_opsworks_app, "type:other").first
    s3region = app[0][:environment][:S3REGION]
    s3bucket = app[0][:environment][:BUCKET]
    s3filename = app[0][:environment][:FILENAME]

    #3  
    s3_client = Aws::S3::Client.new(region: s3region)
    s3_client.get_object(bucket: s3bucket,
                         key: s3filename,
                         response_target: 'C:\inetpub\wwwroot\default.htm')
  end 
  action :run
end
```

此示例使用 [SDK for Ruby v2](https://docs.aws.amazon.com/sdkforruby/api/index.html) 下载文件。但是， OpsWorks Stacks 不会在 Windows 实例上安装此 SDK，因此配方从处理该任务的[https://docs.chef.io/chef/resources.html#chef-gem](https://docs.chef.io/chef/resources.html#chef-gem)资源开始。

**注意**  
`chef_gem` 资源将 gem 安装到 Chef 的专用 Ruby 版本 (配方使用的版本) 中。如果您要为系统范围的 Ruby 版本安装 gem，请使用 [gem\$1package](https://docs.chef.io/chef/resources.html#gem-package) 资源。

大多数配方都是 [https://docs.chef.io/chef/resources.html#ruby-block](https://docs.chef.io/chef/resources.html#ruby-block) 资源，此资源运行使用 SDK for Ruby 下载 `default.htm` 的 Ruby 代码块。`ruby_block` 中的代码可分为下列各节，这些节对应于代码示例中的编号注释。

**1：指定证书捆绑**  
Amazon S3 使用 SSL，因此您需要相应的证书来从 S3 存储桶下载对象。适用于 Ruby v2 的 SDK 不包含证书包，因此您必须提供一个证书包，然后配置适用于 Ruby 的 SDK 才能使用它。 OpsWorks Stacks 不会直接安装证书包，但会安装 Git，其中包括证书包 (`curl-ca-bundle.crt`)。为方便起见，此示例将 SDK for Ruby 配置为使用 SSL 的 Git 证书捆绑。您也可以安装您自己的捆绑并相应地配置开发工具包。

**2：检索存储库数据**  
要从 Amazon S3 下载对象，您需要 Amazon Web Services Region、存储桶名称和密钥名称。如下文所述，此示例通过将一组环境变量与应用程序关联来提供此信息。部署应用程序时， OpsWorks Stacks 会向实例的节点对象添加一组属性。这些属性实际上是包含应用程序配置 (包括环境变量) 的哈希表。此应用程序的应用程序属性看上去将与以下内容类似 (JSON 格式)。  

```
{
  "app_id": "8f71a9b5-de7f-451c-8505-3f35086e5bb3",
  "app_source": {
      "password": null,
      "revision": null,
      "ssh_key": null,
      "type": "other",
      "url": null,
      "user": null
  },
  "attributes": {
      "auto_bundle_on_deploy": true,
      "aws_flow_ruby_settings": {},
      "document_root": null,
      "rails_env": null
  },
  "data_sources": [{"type": "None"}],
  "domains": ["iis_example_app"],
  "enable_ssl": false,
  "environment": {
      "S3REGION": "us-west-2",
      "BUCKET": "windows-example-app",
      "FILENAME": "default.htm"
  },
  "name": "IIS-Example-App",
  "shortname": "iis_example_app",
  "ssl_configuration": {
      "certificate": null,
      "private_key": null,
      "chain": null
  },
  "type": "other",
  "deploy": true
}
```
应用程序的环境变量存储在 `[:environment]` 属性中。要检索它们，请使用 Chef 搜索查询检索应用程序的哈希表（在 `aws_opsworks_app` 节点下）。此应用程序将定义为 `other` 类型，因此查询将搜索此类型的应用程序。配方将利用此实例上只有一个应用程序的事实，因此相关哈希表为 `app[0]`。为方便起见，配方随后将向变量分配区域、存储桶和文件名。  
有关如何使用 Chef 搜索的更多信息，请参阅[使用 Chef 搜索获取属性值](cookbooks-101-opsworks-opsworks-stack-config-search.md)

**3：下载文件**  
配方的第三部分创建一个 [S3 客户端对象](https://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Client.html)并使用其 `[get\$1object](https://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Client.html#get_object-instance_method)` 方法将 `default.htm` 下载到实例的 `C:\inetpub\wwwroot` 目录。

**注意**  
配方是 Ruby 应用程序，因此 Ruby 代码不一定必须位于 `ruby_block` 中。但是，配方正文中的代码先运行，然后再运行资源。在此示例中，如果您将下载代码放入配方正文，则下载将失败，因为 `chef_gem` 资源尚未安装 SDK for Ruby。在 `chef_gem` 资源安装 SDK for Ruby 后，`ruby_block` 资源中的代码将在资源执行时执行。

## 更新实例的说明书
<a name="w2ab1c14c47c17c23c25c19"></a>

OpsWorks Stacks 会自动在新实例上安装自定义食谱。但是，您正在使用现有实例，因此必须手动更新您的说明书。

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

1. 创建 `iis-cookbook` 的 `.zip` 存档，然后将其传到 S3 存储桶。

   这会覆盖现有说明书，但 URL 保持不变，因此您无需更新堆栈配置。

1. 如果您的实例未处于联机状态，请重新启动它。

1. 在实例处于联机状态后，选择导航窗格中的 **Stack**，然后选择 **Run Command**。

1. 对于 **Command**，选择 [Update Custom Cookbooks](workingstacks-commands.md)。此命令将在实例上安装更新后的说明书。

1. 选择 **Update Custom Cookbooks**。此命令可能需要几分钟才能完成。

## 将配方添加到自定义 IIS 层
<a name="w2ab1c14c47c17c23c25c21"></a>

与 `install.rb` 一样，处理部署的首选方式是将 `deploy.rb` 分配给相应的生命周期事件。通常，您将部署配方分配给部署事件，它们统称为部署配方。将配方分配给部署事件不会触发此事件。相反：
+ 对于新实例， OpsWorks Stacks 会在安装配方完成后自动运行 Deploy 配方，因此新实例会自动使用当前的应用程序版本。
+ 对于联机实例，请使用[部署命令](workingapps-deploying.md)手动安装新的或更新的应用程序。

  此命令将在堆栈实例上触发部署事件，该事件将运行部署配方。

**将 deploy.rb 分配给层的部署事件**

1. 在导航窗格中选择 “**图层**”，然后在 “**图层**” 下选择 “**食谱**” IISExample。

1. 在 **Custom Chef Recipes (自定义 Chef 配方)** 下，将 **iis-cookbook::deploy** 添加到 **Deploy (部署)** 配方框并选择 **\$1** 以将配方添加到层。

1. 选择 **Save** 以保存新配置。自定义部署配方现在应包含 `iis-cookbook::deploy`。

## 添加应用程序
<a name="w2ab1c14c47c17c23c25c23"></a>

最后一项任务是向堆栈中添加一个应用程序，以在 OpsWorks Stacks 环境中代表您的应用程序。应用程序包含元数据 (如应用程序的显示名称) 和从存储库下载应用程序所需的数据。

**将应用程序添加到堆栈**

1. 在导航窗格中选择 **Apps**，然后选择 **Add an app**。

1. 使用以下设置配置应用程序。
   + **名称**：I**IIS-Example-App**
   + **存储库类型**：**其他**
   + **环境变量**：添加以下三个环境变量：
     + **S3REGION**：存储桶的区域（在本例中为 `us-west-1`）。
     + **BUCKET**：存储桶名称，例如 `windows-example-app`。
     + **FILENAME**：文件名：**default.htm**。

1. 接受剩余设置的默认值，然后选择 **Add App (添加应用程序)** 以将应用程序添加到堆栈。

**注意**  
此示例使用环境变量来提供下载数据。另一种方法是使用 S3 存档存储库类型并提供文件的 URL。 OpsWorks Stacks 会将信息以及可选数据（例如您的 AWS 证书）添加到应用程序的`app_source`属性中。您的部署配方必须从应用程序属性中获取 URL 并进行解析以提取区域、存储桶名称和文件名。

## 部署应用程序和打开应用程序
<a name="w2ab1c14c47c17c23c25c25"></a>

OpsWorks Stacks 会自动将应用程序部署到新实例，但不会自动部署到在线实例。由于您的实例已在运行中，因此必须手动部署应用程序。

**部署应用程序**

1. 选择导航窗格中的 **Apps**，然后选择应用程序的 **Actions** 列中的 **deploy**。

1. **Command (命令)** 应设置为 **Deploy (部署)**。在**部署应用程序**页面右下角，选择**部署**。此命令可能需要几分钟才能完成。

   在部署完成后，您返回到 **Apps (应用程序)** 页面。**Status (状态)** 指示符显示绿色的 **successful (成功)**，并且应用程序名称旁会出现一个绿色对勾指示部署成功。

**注意**  
Windows 应用程序始终为**其他**应用程序类型，因此部署应用程序将执行以下操作：  
将应用程序的数据添加到[堆栈配置和部署属性](workingcookbook-json.md)，如上文所述。
在堆栈的实例上触发部署事件，该事件将运行自定义部署配方。

**注意**  
有关如何对失败的部署或应用程序执行故障排除的更多信息，请参阅[调试配方](troubleshoot-debug.md)。

应用程序现已安装。您可通过选择**导航**窗格中的**实例**，然后选择实例的公有 IP 地址来打开它。这将向实例发送 HTTP 请求，并且浏览器中应显示与以下内容类似的信息。

![\[Text displaying "Hello World!" in large, bold font against a white background.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/windows-iis-app.png)
