

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

# 使用 Amazon S3 存储桶
<a name="gettingstarted.walkthrough.photoapp"></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 支持 团队联系。

应用程序通常使用 Amazon Simple Storage Service (Amazon S3)存储桶来存储图像或其他媒体文件等大型项目。尽管 OpsWorks Stacks 不提供对 Amazon S3 的集成支持，但您可以轻松地自定义堆栈以允许您的应用程序使用 Amazon S3 存储。本主题向您演示了向应用程序提供 Amazon S3 访问权限的基本过程，使用带有 PHP 应用程序服务器的 Linux 堆栈为例。基本原则同样适用于 Windows 堆栈。

发送到 Amazon S3 存储桶的内容可能包含客户内容。有关删除敏感数据的更多信息，请参阅[如何清空 S3 存储桶？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/empty-bucket.html)或[如何删除 S3 存储桶？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html)。

**Topics**
+ [步骤 1：创建 Amazon S3 存储桶](using-s3-bucket.md)
+ [步骤 2：创建 PHP App Server 堆栈](using-s3-stack.md)
+ [步骤 3：创建和部署自定义说明书](using-s3-cookbook.md)
+ [第 4 步：为 LifeCycle 活动分配食谱](using-s3-events.md)
+ [步骤 5：将访问信息添加到堆栈配置和部署属性](using-s3-json.md)
+ [步骤 6：部署并运行 PhotoApp](using-s3-run.md)

# 步骤 1：创建 Amazon S3 存储桶
<a name="using-s3-bucket"></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 支持 团队联系。

您必须先创建 Amazon S3 存储桶。您可以使用 Amazon S3 控制台、API 或 CLI 来直接完成此操作，不过创建资源更简单的方法通常是使用 CloudFormation 模板。以下模板为此示例创建 Amazon S3 存储桶，并设置具有 [IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html)的[实例配置文件](https://docs.aws.amazon.com/IAM/latest/UserGuide/WorkingWithRoles.html)，授予对存储桶的无限制访问权限。然后，您可以使用层设置来将实例配置文件附加到堆栈的应用程序服务器实例，这会允许应用程序访问存储桶，如下文所述。实例配置文件的实效性不限制为 Amazon S3，对于集成各种 Amazon Web Service 非常有价值。

```
{
   "AWSTemplateFormatVersion" : "2010-09-09",
   "Resources" : {
      "AppServerRootRole": {
         "Type": "AWS::IAM::Role",
         "Properties": {
            "AssumeRolePolicyDocument": {
               "Statement": [ {
                  "Effect": "Allow",
                  "Principal": {
                     "Service": [ "ec2.amazonaws.com" ]
                  },
                  "Action": [ "sts:AssumeRole" ]
               } ]
            },
            "Path": "/"
         }
      },
      "AppServerRolePolicies": {
         "Type": "AWS::IAM::Policy",
         "Properties": {
            "PolicyName": "AppServerS3Perms",
            "PolicyDocument": {
               "Statement": [ {
                  "Effect": "Allow",
                  "Action": "s3:*",
                  "Resource": { "Fn::Join" : ["", [ "arn:aws:s3:::", { "Ref" : "AppBucket" } , "/*" ]
                  ] }
               } ]
            },
            "Roles": [ { "Ref": "AppServerRootRole" } ]
         }
      },
      "AppServerInstanceProfile": {
         "Type": "AWS::IAM::InstanceProfile",
         "Properties": {
            "Path": "/",
            "Roles": [ { "Ref": "AppServerRootRole" } ]
         }
      },
     "AppBucket" : {
      "Type" : "AWS::S3::Bucket"
      }
   },
   "Outputs" : {
       "BucketName" : {
           "Value" : { "Ref" : "AppBucket" }
       },
       "InstanceProfileName" : {
           "Value" : { "Ref" : "AppServerInstanceProfile" }
       }
   }
}
```

在您启动模板时，将发生几件事：
+ `[AWS::S3::Bucket](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html)` 资源创建 Amazon S3 存储桶。
+ `[AWS::IAM::InstanceProfile](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html)` 资源创建将分配到应用程序服务器实例的实例配置文件。
+ `[AWS::IAM::Role](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)` 资源创建实例配置文件的角色。
+ `[AWS::IAM::Policy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-policy.html)` 资源将角色的权限设置为允许不受限制地访问 Amazon S3 存储桶。
+ 在您启动模板之后，`Outputs` 部分在 CloudFormation 控制台中显示存储桶和实例配置文件名称。

  您需要这些值来设置堆栈和应用程序。

有关如何创建 CloudFormation 模板的更多信息，请参阅[学习模板基础知识](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/gettingstarted.templatebasics.html)。

**创建 Amazon S3 存储桶**

1. 将示例模板复制到系统上的文本文件。

   此示例假定文件名为 `appserver.template`。

1. 打开 [CloudFormation](https://console.aws.amazon.com/cloudformation/) 控制台并选择**创建堆栈**。

1. 在 **Stack Name** 框中，输入堆栈名称。

   此示例假定名称为 **AppServer**。

1. 请依次选择 **Upload template file (上传模板文件)**、**Browse (浏览)**、您在步骤 1 中创建的 `appserver.template` 文件以及 **Next Step (下一步)**。

1. 在 **Specify Parameters (指定参数)** 页面上，选择 **I acknowledge that this template may create IAM resources (我确认，此模板可创建 IAM 资源)**，然后在向导的各页面上选择 **Next Step (下一步)**，直至您完成。选择**创建**。

1. **AppServer**堆栈达到 **CREATE\$1COMPLETE** 状态后，将其选中并选择 “**输出**” 选项卡。

   您可能需要刷新几次来更新状态。

1. 在 “**输出**” 选项卡上，记录**BucketName**和**InstanceProfileName**值以备后用。

**注意**  
CloudFormation 使用术语*堆栈*来指根据模板创建的资源集合；它与堆栈 OpsWorks 堆栈不同。

# 步骤 2：创建 PHP App Server 堆栈
<a name="using-s3-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 支持 团队联系。

堆栈包含两层， PHP App Server 和 MySQL，每一层有一个实例。应用程序在 Amazon S3 存储桶上存储照片，但使用 MySQL 实例作为后端数据存储，用于存储每张照片的元数据。

发送到 Amazon S3 存储桶的内容可能包含客户内容。有关删除敏感数据的更多信息，请参阅[如何清空 S3 存储桶？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/empty-bucket.html)或[如何删除 S3 存储桶？](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html)。

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

1. 创建一个为本示例命名为 **PhotoSite** 的新堆栈，然后添加一个 PHP App Server 层。您可以为两者使用默认设置。有关更多信息，请参阅[创建新堆栈](workingstacks-creating.md)和[创建图 OpsWorks 层](workinglayers-basics-create.md)。

1. 在 **层** 页面上，对于 PHP App Server，选择 **安全性**，然后选择 **编辑**。

1. 在**层配置文件**部分，选择您在启动 AppServer CloudFormation 堆栈后之前记录的实例配置文件名称。会是这样的`AppServer-AppServerInstanceProfile-1Q3KD0DNMGB90`。 OpsWorks Stacks 会将此配置文件分配给该层的所有亚马逊 EC2 实例，从而向在该层实例上运行的应用程序授予访问您的 Amazon S3 存储桶的权限。  
![\[IAM Instance Profile dropdown showing available profiles, including a custom AppServer profile.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/photoapp_profile.png)

1. 将一个实例添加到 PHP App Server 层，并启动该实例。有关如何添加和启动实例的更多信息，请参阅[将实例添加到层](workinginstances-add.md)。

1. 添加 MySQL 层到堆栈，添加实例，然后启动它。您可以同时为层和实例使用默认设置。特别是，MySQL 实例不需要访问 Amazon S3 存储桶，因此它可以使用默认选择的标准 OpsWorks 堆栈实例配置文件。

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

堆栈尚未就绪：
+ 您的应用程序需要一些信息来访问 MySQL 数据库服务器和 Amazon S3 存储桶，例如数据库主机名和 Amazon S3 存储桶名称。
+ 您需要在 MySQL 数据库服务器中设置数据库，并创建表来保存照片的元数据。

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

在此示例中，食谱已为您实现并存储在[公共存储 GitHub 库](https://github.com/amazonwebservices/opsworks-example-cookbooks/tree/master/photoapp)中。说明书包含两个配方 `appsetup.rb` 和 `dbsetup.rb`，以及一个模板文件 `db-connect.php.erb`。

`appsetup.rb` 配方将创建配置文件，其中包含应用程序访问数据库和 Amazon S3 存储桶所需信息。它基本上是 [将应用程序连接到数据库](gettingstarted-db-recipes.md#gettingstarted-db-recipes-appsetup) 中所述的 `appsetup.rb` 配方经过略微修改的版本。主要差别在于传递到模板的变量，这代表了访问信息。

前四个属性定义数据库连接设置，由 OpsWorks 堆栈在创建 MySQL 实例时自动定义。

这些变量与原始配方中的变量之间有两个主要差别：
+ 与原始配方一样，`table` 变量表示由 `dbsetup.rb` 创建的数据库表的名称，并设置为在说明书的属性文件中定义的属性的值。

  但是，该属性有不同的名称：`[:photoapp][:dbtable]`。
+ `s3bucket` 变量特定于此示例，设置为表示 Amazon S3 存储桶名称的属性 `[:photobucket]` 的值。

   `[:photobucket]` 使用自定义 JSON 定义，如下文所述。有关属性的更多信息，请参阅[属性](workingcookbook-installingcustom-components-attributes.md)。

有关属性的更多信息，请参阅[属性](workingcookbook-installingcustom-components-attributes.md)。

`dbsetup.rb` 配方设置数据库表用于保存各个照片的元数据。它基本上是 `dbsetup.rb` 中所述的 [设置数据库](gettingstarted-db-recipes.md#gettingstarted-db-recipes-dbsetup) 配方经过略微修改的版本；有关详细说明，请参阅该主题。

此示例与原始配方之间的唯一差别是数据库架构，它有三列，包含 ID、URL 和各照片的标题，存储在 Amazon S3 存储桶中。

食谱已经实现了，所以你所需要做的就是将 photoapp 食谱部署到每个实例的食谱缓存中。 OpsWorks 然后，当相应的生命周期事件发生时，Stacks 会运行缓存的配方，如下所述。

**部署 photoapp 说明书**

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

1. 在 **Configuration Management** 部分中：
   + 将 **Use custom Chef cookbooks** 设置为 **Yes**。
   + 将 **Repository type** 设置为 Git。
   + 将 **Repository URL (存储库 URL)** 设置为 **git://github.com/amazonwebservices/opsworks-example-cookbooks.git**。

1. 在 **Stack (堆栈)** 页面上，依次选择 **Run Command (运行命令)**、**Update Custom Cookbooks (更新自定义说明书)** 堆栈命令以及 **Update Custom Cookbooks (更新自定义说明书)**，以将新说明书安装到实例说明书缓存中。  
![\[Run Command interface showing Update Custom Cookbooks option and instance selection.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/redis_walkthrough_command.png)

# 第 4 步：为 LifeCycle 活动分配食谱
<a name="using-s3-events"></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 支持 团队联系。

你可以[手动](workingcookbook-manual.md)运行自定义配方，但最好的方法通常是让 OpsWorks Stacks 自动运行它们。每层都有一组内置配方，分配到 Setup、Configure、Deploy、Undeploy 和 Shutdown 这五个[生命周期事件](workingcookbook-events.md)。每次实例上发生事件时， OpsWorks Stacks 都会为实例的每个层运行关联配方，这些配方处理所需的任务。例如，当实例完成启动时， OpsWorks Stacks 会触发安装事件来运行安装配方，该配方通常处理安装和配置软件包等任务。

通过将每个配方分配给相应的生命周期事件，可以让 OpsWorks Stacks 在图层的实例上运行自定义配方。 OpsWorks 图层的内置配方完成后，堆栈将运行任何自定义配方。在本示例中，分配`appsetup.rb`给 PHP 应用服务器层的 Deploy 事件和 `dbsetup.rb` MySQL 层的 Deploy 事件。 OpsWorks 然后，堆栈将在启动期间、内置安装配方完成后、每次部署应用程序时、构建的 Deploy 配方完成后，在关联层的实例上运行配方。有关更多信息，请参阅 [自动运行配方](workingcookbook-assigningcustom.md)。

**将自定义配方分配到层的部署事件**

1. 在 OpsWorks Stacks L **ay** ers 页面上，对于 PHP App Server，选择**食谱**，然后选择**编辑**。

1. 在 **Custom Chef Recipes (自定义 Chef 配方)** 下，将配方名称添加到 Deploy 事件，然后选择 **\$1**。该名称必须为 Chef `cookbookname::recipename` 格式，其中 `recipename` 不包括 `.rb` 扩展名。对于此示例，您输入 `photoapp::appsetup`。然后选择 **Save (保存)** 以更新层配置。  
![\[Custom Chef Recipes configuration with Repository URL and lifecycle events.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/psb6a.png)

1. 在 **层** 页面上，选择 MySQL 层的 **操作** 列中的 **编辑**。

1. 将 `photoapp::dbsetup` 添加到层的部署事件，然后保存新配置。

# 步骤 5：将访问信息添加到堆栈配置和部署属性
<a name="using-s3-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 支持 团队联系。

`appsetup.rb`配方取决于[堆栈 OpsWorks 堆栈配置和部署属性的](workingcookbook-json.md)数据，这些数据安装在每个实例上，包含有关堆栈和任何已部署应用程序的详细信息。对象的 `deploy` 属性具有以下结构，为便利起见显示为 JSON：

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

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

自定义配方依赖于代表数据库和 Amazon S3 访问信息的多个堆栈配置和部署属性：
+ 数据库连接属性（例如`[:deploy][:database][:host]`）由 OpsWorks Stacks 在创建 MySQL 层时定义。
+ 表名称属性 `[:photoapp][:dbtable]` 在自定义说明书的属性文件中定义，并设置为 `foto`。
+ 您必须使用自定义 JSON 将属性添加到堆栈配置和部署属性，以此来定义存储桶名称属性 `[:photobucket]`。

**定义 Amazon S3 存储桶名称属性**

1. 在**堆栈 OpsWorks 堆栈**页面上，选择**堆栈设置**，然后选择**编辑**。

1. 在 **Configuration Management** 部分中，将访问信息添加到 **Custom Chef JSON** 框中。它应与以下内容类似：

   ```
   {
     "photobucket" : "yourbucketname"
   }
   ```

   *yourbucketname*替换为您在中记录的存储桶名称[步骤 1：创建 Amazon S3 存储桶](using-s3-bucket.md)。  
![\[Custom Chef cookbook configuration with Git repository and JSON settings.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/photoapp_walkthrough_json.png)

OpsWorks 堆栈将自定义 JSON 合并到堆栈配置和部署属性中，然后再将其安装到堆栈的实例上；然后`appsetup.rb`可以从该`[:photobucket]`属性中获取存储桶名称。如果要更改存储桶，您并不需要接触配方；只需[覆盖属性](workingcookbook-attributes.md)来提供新存储桶名称。

# 步骤 6：部署并运行 PhotoApp
<a name="using-s3-run"></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 支持 团队联系。

在本示例中，该应用程序也已为您实现并存储在[公共存储 GitHub 库](https://github.com/amazonwebservices/opsworks-demo-php-photo-share-app)中。您只需将应用程序添加到堆栈，将其部署到应用程序服务器，然后运行它。

**将应用程序添加到堆栈并将其部署到应用程序服务器**

1. 打开 **Apps (应用程序)** 页面，然后选择 **Add an app (添加应用程序)**。

1. 在 **Add App** 页面上，执行以下操作：
   + 将**名称**设置为 **PhotoApp**。
   + 将 **App type** 设置为 **PHP**。
   + 将 **Document root (文档根目录)** 设置为 **web**。
   + 将 **Repository type** 设置为 **Git**。
   + 将 **Repository URL (存储库 URL)** 设置为 **git://github.com/awslabs/opsworks-demo-php-photo-share-app.git**。
   + 选择 **Add App (添加应用程序)** 以接受其他设置的默认值。  
![\[Form to add an app with fields for name, type, document root, and repository details.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/photoapp_walkthrough_app.png)

1. 在**应用程序**页面上，在 PhotoApp 应用程序的**操作**列中选择**部署**。  
![\[Apps page showing PhotoApp with deploy, edit, and delete options in the Actions column.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/photoapp_walkthrough_deploy.png)

1. 接受默认值，然后选择 **Deploy (部署)** 以将应用程序部署到服务器。

要运行 PhotoApp，请转到**实例**页面并选择 PHP App Server 实例的公有 IP 地址。

![\[PHP App Server instance details showing hostname, status, and public IP address.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/photoapp_walkthrough_run.png)


您应看到以下用户界面。选择 **添加照片**以在 Amazon S3 存储桶上存储照片，并在后端数据存储中存储元数据。

![\[User interface section titled "My Photos" with an "Add a Photo" button.\]](http://docs.aws.amazon.com/zh_cn/opsworks/latest/userguide/images/photoapp_walkthrough_ui.png)
