

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

# 使用 AWS Service Catalog 约束
<a name="constraints"></a>

您可以应用约束，以控制当最终用户启动特定组合中的产品时所应用的规则。当最终用户启动产品时，他们将看到您已使用约束应用的规则。您可以在产品放入产品组合后将约束应用于产品。约束一经创建便立即生效，并且它们已应用于尚未启动的产品的所有当前版本。

**Topics**
+ [启动约束](constraints-launch.md)
+ [通知约束](constraints-notification.md)
+ [标签更新约束](constraints-resourceupdate.md)
+ [堆栈集约束](constraints-stackset.md)
+ [模板约束](catalogs_constraints_template-constraints.md)

# AWS Service Catalog 启动限制
<a name="constraints-launch"></a>

启动约束指定最终用户启动、更新或终止产品时所扮演的 AWS Identity and Access Management (IAM) 角色。 AWS Service Catalog IAM 角色是用户或 AWS 服务可以临时承担的使用 AWS 服务的权限集合。有关介绍性示例，请参阅：
+ CloudFormation 产品类型:[步骤 6：添加启动约束以分配 IAM 角色](getstarted-launchconstraint.md)
+ Terraform 开源或 Terraform 云产品类型：[步骤 5：创建启动角色](getstarted-launchrole-Terraform.md)

启动约束适用于产品组合中的产品（产品-产品组合关联）。启动约束不适用于产品组合层面，也不适用于跨所有产品组合的某个产品。要将启动约束与产品组合中的所有产品相关联，您必须将启动约束分别应用于每个产品。

如果没有启动约束，最终用户必须使用自己的 IAM 凭证启动和管理产品。为此，他们必须拥有产品使用的 AWS 服务的权限，以及 AWS Service Catalog。 CloudFormation通过使用启动角色，您可改为将最终用户的权限限定为他们对该产品所需的最小权限。有关最终用户权限的更多信息，请参阅[Identity and Access Management AWS Service Catalog](controlling_access.md)。

要创建和分配 IAM 角色，您必须拥有以下 IAM 管理权限：
+ `iam:CreateRole`
+ `iam:PutRolePolicy`
+ `iam:PassRole`
+ `iam:Get*`
+ `iam:List*`

## 配置启动角色
<a name="constraints-launch-role"></a>

您向产品分配的作为启动约束的 IAM 角色必须拥有使用以下项的权限：

**对于 Cloudformation 产品**
+ `arn:aws:iam::aws:policy/AWSCloudFormationFullAccess` CloudFormation 托管策略
+ 产品 AWS CloudFormation 模板中的服务
+ 在服务拥有的 Amazon S3 存储桶中读取 AWS CloudFormation 模板的访问权限。

**对于 Terraform 产品**
+ 产品的 Amazon S3 模板中使用的服务
+ 自服务拥有的 Amazon S3 存储桶中读取 Amazon S3 模板的访问权限。
+ `resource-groups:Tag` 用于在 Amazon EC2 实例中进行标记（Terraform 预配置引擎在执行配置操作时担任）
+ `resource-groups:CreateGroup`用于资源组标记（假设 AWS Service Catalog 用于创建资源组和分配标签） 

IAM 角色的信任策略必须 AWS Service Catalog 允许代入该角色。在以下步骤中，当您选择角色类型时 AWS Service Catalog ，将自动设置信任策略。如果您不使用控制台，请参阅[如何在 IAM 角色中使用*信任策略中的为代入角色的 AWS 服务创建*信任策略](https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/)部分。

**注意**  
无法在启动角色中分配 `servicecatalog:ProvisionProduct`、`servicecatalog:TerminateProvisionedProduct` 和 `servicecatalog:UpdateProvisionedProduct` 权限。您必须使用 IAM 角色，如[授予 AWS Service Catalog 最终用户权限](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/getstarted-iamenduser.html)部分中的内联策略步骤所示。

**注意**  
要在 AWS Service Catalog 控制台中查看预配置的 Cloudformation 产品和资源，最终用户需要 CloudFormation 读取权限。在控制台中查看预配置产品和资源**不会**使用启动角色。

**创建启动角色**

1. 使用 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 打开 IAM 控制台。

   Terraform 产品需要额外的启动角色配置。有关更多信息，请查看 *Terraform 开源产品入门*中的[步骤 5：创建启动角色](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/getstarted-launchrole-Terraform)。

1. 选择 **角色**。

1. 选择**创建新角色**。

1. 输入角色名称并选择 **Next Step**。

1. 在 **AWS Service Catalog** 旁边的**AWS 服务角色**下，选择**选择**。

1. 在 **Attach Policy** 页面上，选择 **Next Step**。

1. 要创建角色，请选择 **Create Role**。

**将策略附加到新角色**

1. 选择您创建的角色以查看角色详细信息页面。

1. 选择 **Permissions** 选项卡，展开 **Inline Policies** 部分。然后选择 **click here**。

1. 选择 **Custom Policy**，然后选择 **Select**。

1. 输入策略的名称，然后将以下内容粘贴到 **Policy Document** 编辑器中：

   ```
     
             "Statement":[
         {
            "Effect":"Allow",
            "Action":[
               "s3:GetObject"
            ],
            "Resource":"*",
            "Condition":{
               "StringEquals":{
                  "s3:ExistingObjectTag/servicecatalog:provisioning":"true"
               }
            }
      ]
   }
   ```
**注意**  
为启动约束配置启动角色时，您必须使用以下字符串：`"s3:ExistingObjectTag/servicecatalog:provisioning":"true"`。

1. 为产品使用的每个额外服务的策略添加一行。例如，要为 Amazon Relational Database Service（Amazon RDS）添加权限，请在 `Action` 列表中的最后一行的末尾键入逗号，然后添加以下行：

   ```
   "rds:*"
   ```

1. 选择**应用策略**。

## 应用启动约束
<a name="constraints-launch-constraint"></a>

您配置启动角色后，将该角色作为启动约束分配给产品。此操作指示 AWS Service Catalog 在最终用户启动产品时代入该角色。

**将角色分配给产品**

1. 打开 Service Catalog 控制台，网址为[https://console.aws.amazon.com/servicecatalog/](https://console.aws.amazon.com/servicecatalog/)。

1. 选择包含产品的产品组合。

1. 选择**约束**选项卡并选择**创建约束**。

1. 自**产品**中选择产品，然后在**约束类型**下选择**启动**。选择**继续**。

1. 在**启动约束** 部分，您可以从自己的账户中选择 IAM 角色、输入 IAM 角色 ARN 或输入角色名称。

   如果您指定角色名称，当账户使用启动约束时，将使用账户中具有该名称的 IAM 角色。此方法允许使用与账户无关的启动角色约束，因此您可以为每个共享账户创建更少的资源。
**注意**  
在创建启动约束的账户中，以及使用此启动约束启动产品的用户账户中，都必须存在给定的角色名称。

1. 指定 IAM 角色后，选择 **创建**。

## 在启动限制中添加混淆代理
<a name="constraint-confused-deputy"></a>

AWS Service Catalog 支持使用代入角色请求 APIs 的[混乱副](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)手保护。添加启动约束时，您可以使用启动角色信任策略中的 `sourceAccount` 和 `sourceArn` 条件来限制启动角色访问权限。它可确保启动角色由可信来源调用。

在以下示例中， AWS Service Catalog 最终用户属于账户 111111111111。 AWS Service Catalog 管理员为产品创建 `LaunchConstraint` 时，最终用户可以在启动角色信任策略中指定以下条件，将担任角色限制为账户 111111111111。

```
"Condition":{
   "ArnLike":{
      "aws:SourceArn":"arn:aws:servicecatalog:us-east-1:111111111111:*"
   },
   "StringEquals":{
      "aws:SourceAccount":"111111111111"
   }
  
}
```

使用 `LaunchConstraint` 预配置产品的用户必须具有相同的 `AccountId`（111111111111）。否则，为防止滥用启动角色，操作将出现 `AccessDenied` 错误并失败。

以下 AWS Service Catalog APIs 是为了保护混乱的副手：
+ `LaunchConstraint`
+ `ProvisionProduct`
+ `UpdateProvisionedProduct`
+ `TerminateProvisionedProduct`
+ `ExecuteProvisionedProductServiceAction`
+ `CreateProvisionedProductPlan`
+ `ExecuteProvisionedProductPlan`

 AWS Service Catalog 仅对的`sourceArn `保护支持模板化 ARNs，例如 “`arn:<aws-partition>:servicecatalog:<region>:<accountId>:`” 它不支持特定的资源 ARNs。

## 验证启动约束
<a name="constraints-launch-test"></a>

要验证 AWS Service Catalog 使用角色启动产品并成功配置产品，请从 AWS Service Catalog 控制台启动产品。要在将约束发布给用户前对其进行测试，请创建包含相同产品的测试产品组合，并使用该产品组合测试约束。

**启动产品**

1. 在 AWS Service Catalog 控制台的菜单中，选择 S **ervice Catalog**，**最终用户**。

1. 选择产品以打开**产品详细信息**页面。在**启动选项**表中，确认已显示角色的 Amazon 资源名称（ARN）。

1. 选择**启动产品**。

1. 继续执行启动步骤，填入任何所需信息。

1. 确认产品已成功启动。

# AWS Service Catalog 通知限制
<a name="constraints-notification"></a>

**注意**  
AWS Service Catalog 不支持 Terraform 开源或 Terraform Cloud 产品的通知限制。

通知约束指定 Amazon SNS 主题以接收有关堆栈事件的通知。

使用以下过程创建 SNS 主题并订阅它。

**创建 SNS 主题和订阅**

1. [在 v3/home 上打开亚马逊 SNS 控制台。https://console.aws.amazon.com/sns/](https://console.aws.amazon.com/sns/v3/home)

1. 选择**创建主题**。

1. 键入主题名称，然后选择 **创建主题**。

1. 选择**创建订阅**。

1. 对于**协议**，请选择**电子邮件**。对于 **Endpoint**，请键入您用于接收通知的电子邮件地址。选择**创建订阅**。

1. 您将收到一封包含主题行 `AWS Notification - Subscription Confirmation` 的确认电子邮件。打开电子邮件，然后按照说明操作以完成订阅。

通过以下过程使用您在上一过程中创建的 SNS 主题应用通知约束。

**向产品应用通知约束**

1. 打开 Service Catalog 控制台，网址为[https://console.aws.amazon.com/servicecatalog/](https://console.aws.amazon.com/servicecatalog/)。

1. 选择包含产品的产品组合。

1. 展开**约束**并选择**添加约束**。

1. 从**产品**中选择产品并将**约束类型**设置为**通知**。选择**继续**。

1. 选择 **Choose a topic from your account**，然后选择您根据 **Topic Name** 创建的 SNS 主题。

1. 选择**提交**。

# AWS Service Catalog 标签更新限制
<a name="constraints-resourceupdate"></a>

**注意**  
AWS Service Catalog 不支持 Terraform 开源产品的标签更新限制。

通过标签更新限制， AWS Service Catalog 管理员可以允许或禁止最终用户更新与预配置产品关联的资源上的标签。如果允许更新标签，则与产品或产品组合关联的新标签将在预配置产品更新期间应用于预配置的资源。

**启用产品的标签更新**

1. 打开 Service Catalog 控制台，网址为[https://console.aws.amazon.com/servicecatalog/](https://console.aws.amazon.com/servicecatalog/)。

1. 选择包含要更新的产品的产品组合。

1. 选择**约束** 选项卡并选择**添加约束**。

1. 在**约束类型**下，选择**标签更新**。

1. 从**产品**中选择产品，然后选择**继续**。

1. 在**标签更新**页面上，选择**启用标签更新**。

1. 选择**提交**。

# AWS Service Catalog 堆栈集约束
<a name="constraints-stackset"></a>

**注意**  
AWS Service Catalog 不支持 Terraform 开源产品的堆栈集约束。
AutoTags 目前不支持 CloudFormation StackSets。

堆栈集约束允许您使用配置产品部署选项 CloudFormation StackSets。您可以为产品启动指定多个账户和区域。最终用户可以管理这些账户，并确定产品的部署位置和部署顺序。

**向产品应用堆栈集约束**

1. 打开 Service Catalog 控制台，网址为[https://console.aws.amazon.com/servicecatalog/](https://console.aws.amazon.com/servicecatalog/)。

1. 选择包含所需产品的产品组合。

1. 选择**约束**选项卡并选择**创建约束**。

1. 在**产品**中，选择产品。在**约束类型**中，选择**堆栈集**。

1. 为您的堆栈集约束配置账户、区域和权限。
   + 在**账户设置**中，确定要在其中创建产品的账户。
   + 在**区域设置**中，选择要部署产品的地理区域以及在这些区域中您希望的产品部署顺序。
   + 在**权限**中，选择一个 IAM StackSet 管理员角色来管理您的目标账户。如果您不选择角色，则 StackSets使用默认 ARN。[了解有关设置堆栈集权限的更多信息。](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-prereqs.html)

1. 选择**创建**。

# AWS Service Catalog 模板约束
<a name="catalogs_constraints_template-constraints"></a>

**注意**  
AWS Service Catalog 不支持 Terraform 开源或 Terraform Cloud 产品的模板限制。

要限制最终用户在启动产品时可用的选项，请应用模板约束。应用模板约束可确保最终用户可在不违反组织的合规性要求的情况下使用产品。您可以将模板约束应用于产品 AWS Service Catalog 组合中的产品。产品组合必须先包含一个或多个产品，然后才能定义模板约束。

模板约束由一个或多个规则组成，这些规则缩小了在产品基础 CloudFormation 模板中定义的参数的允许值。 CloudFormation 模板中的参数定义用户在创建堆栈时指定的值的集合。例如，参数可以定义用户在启动包含实例的堆栈时可以选择的各种 EC2 实例类型。

如果模板中的参数值集对于产品组合的目标受众来说太广泛，则可定义模板约束来限制用户在启动产品时可选择的值。例如，如果模板参数包含的 EC2 实例类型对于仅应使用小实例类型（例如`t2.micro`或`t2.small`）的用户来说太大，则可以添加模板约束来限制最终用户可以选择的实例类型。有关 CloudFormation 模板参数的更多信息，请参阅《*CloudFormation 用户指南*》中的[参数](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html)。

模板约束绑定于产品组合内。如果将模板约束应用于一个产品组合的某个产品，然后您将此产品包含在另一个产品组合中，则这些约束将不会应用于第二个产品组合的此产品。

如果将模板约束应用于已与用户共享的产品，则约束会立即应用到随后启动的所有产品和产品组合中所有版本的产品。

您可以使用规则编辑器或在 AWS Service Catalog 管理员控制台中将规则写成 JSON 文本来定义模板约束规则。有关规则的更多信息（包括语法和示例），请参阅[模板约束规则](reference-template_constraint_rules.md)。

要在将约束发布给用户前对其进行测试，请创建包含相同产品的测试产品组合，并使用该产品组合测试约束。

**将模板约束应用于产品**

1. 打开 Service Catalog 控制台，网址为[https://console.aws.amazon.com/servicecatalog/](https://console.aws.amazon.com/servicecatalog/)。

1. 在**产品组合**页面，选择包含要将模板约束应用于其上的产品的产品组合。

1. 展开**约束**部分并选择**添加约束**。

1. 在**选择产品和类型**窗口中，对于**产品**，选择您要定义模板约束的产品。然后，对于**约束类型**项，选择**模板**。选择**继续**。

1. 在**模板约束生成器**页面，使用 JSON 编辑器或规则生成器界面来编辑约束规则。
   + 要编辑规则的 JSON 代码，请选择**约束文本编辑器**选项卡。此选项卡上提供了多个示例来帮助您开始操作。

     要使用规则生成器界面构建规则，请选择**规则生成器**选项卡。在此选项卡上，您可以选择产品的模板中指定的任何参数，并可以为该参数指定允许值。根据参数的类型，可通过选择清单中的项目、指定数量或指定逗号分隔列表中的一组值来指定允许值。

     在构建完规则后，选择**添加规则**。规则会显示在**规则生成器**选项卡上的表中。要查看和编辑 JSON 输出，请选择**约束文本编辑器**选项卡。

1. 在编辑完约束的规则后，选择**提交**。要查看约束，请转到产品组合详细信息页，然后展开**约束**。

# 模板约束规则
<a name="reference-template_constraint_rules"></a>

在 AWS Service Catalog 产品组合中定义模板约束的规则描述了最终用户何时可以使用该模板，以及他们可以为用于创建他们尝试使用的产品的 CloudFormation 模板中声明的参数指定哪些值。规则可用于防止最终用户无意中指定错误的值。例如，您可以添加一条规则来验证最终用户是否在给定 VPC 中指定了有效的子网，或者是否在测试环境中使用了`m1.small`实例类型。 CloudFormation 在为产品创建资源之前，使用规则来验证参数值。

每个规则包含两个属性：规则条件（可选）和断言（必需）。规则条件确定规则的生效时间。断言描述用户可为特定参数指定的值。如果您未定义规则条件，则规则的断言始终生效。要定义规则条件和断言，可使用*特定于规则的内部函数*，只能在模板的 `Rules` 部分中使用这些函数。您可以嵌套函数，但规则条件或断言的最终结果必须为 true 或 false。

例如，假设您在 `Parameters` 部分中声明了 VPC 和子网参数。您可以创建一个规则来验证给定子网是否位于特定的 VPC 中。因此，当用户指定 VPC 时，会在创建或更新堆栈之前 CloudFormation 评估断言以检查子网参数值是否在该 VPC 中。如果参数值无效，则 CloudFormation 立即无法创建或更新堆栈。如果用户未指定 VPC，则 CloudFormation 不检查子网参数值。

## 语法
<a name="template-constraint-rules-syntax"></a>

模板的`Rules` 部分由后跟冒号的密钥名称 `Rules` 组成。所有规则声明都被括在括号里。如果您声明多个规则，则可用逗号将它们分隔开。对于每个规则，您必须声明一个用引号引起来的逻辑名称，后跟冒号以及将规则条件和断言括起来的括号。

规则可以包含 `RuleCondition` 属性，且必须包含 `Assertions` 属性。对于每个规则，您可以仅定义一个规则条件；您可以在 `Assertions` 属性内定义一个或多个断言。可以通过使用特定于规则的内部函数定义规则条件和断言，如以下伪模板所示：

```
"Rules":{
   "Rule01":{
      "RuleCondition":{
         "Rule-specific intrinsic function"
      },
      "Assertions":[
         {
            "Assert":{
               "Rule-specific intrinsic function"
            },
            "AssertDescription":"Information about this assert"
         },
         {
            "Assert":{
               "Rule-specific intrinsic function"
            },
            "AssertDescription":"Information about this assert"
         }
      ]
   },
   "Rule02":{
      "Assertions":[
         {
            "Assert":{
               "Rule-specific intrinsic function"
            },
            "AssertDescription":"Information about this assert"
         }
      ]
   }
}
```

此伪模板显示包含两个分别名为 `Rules` 和 `Rule01` 的规则的 `Rule02` 部分。`Rule01` 包含一个规则条件和两个断言。如果规则条件中的函数的计算结果为 true，则将计算和应用每个断言中的函数。如果规则条件为 false，则此规则不会生效。由于 `Rule02` 没有规则条件（这意味着始终计算和应用断言），因此它始终生效。

有关用于定义规则条件和断言的特定于规则的内置函数信息，请参阅*AWS CloudFormation 《用户指南》*中的[AWS 规则函数](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-rules.html)。

## 示例：按条件验证参数值
<a name="template-constraint-rules-example"></a>

以下两个规则检查 `InstanceType` 参数的值。根据环境参数（`test` 或 `prod`）的值，用户必须为 `m1.small` 参数指定 `m1.large` 或 `InstanceType`。必须在同一模板的 `InstanceType` 部分中声明 `Environment` 和 `Parameters` 参数。

```
"Rules" : {
  "testInstanceType" : {
    "RuleCondition" : {"Fn::Equals":[{"Ref":"Environment"}, "test"]},
    "Assertions" : [
      {
        "Assert" :  { "Fn::Contains" : [ ["m1.small"], {"Ref" : "InstanceType"} ] },
        "AssertDescription" : "For the test environment, the instance type must be m1.small"
      }
    ]
  },
  "prodInstanceType" : {
    "RuleCondition" : {"Fn::Equals":[{"Ref":"Environment"}, "prod"]},
    "Assertions" : [
      {
        "Assert" :  { "Fn::Contains" : [ ["m1.large"], {"Ref" : "InstanceType"} ] },
        "AssertDescription" : "For the prod environment, the instance type must be m1.large"
      }
    ]
  }
}
```