

# 授予自行管理的权限
<a name="stacksets-prereqs-self-managed"></a>

本主题提供有关如何创建 StackSets 所需的 IAM 服务角色，以通过*自行管理*权限跨账户和 Amazon Web Services 区域 进行部署的说明。对于在您管理 StackSet 所用的账户与您将堆栈实例部署到的账户之间建立信任关系，这些角色必不可少。使用此权限模型，StackSets 可以部署到您有权创建 IAM 角色的任何 Amazon Web Services 账户 中。

要使用*服务托管*权限，请参阅 [激活可信访问权限](stacksets-orgs-activate-trusted-access.md)。

**Topics**
+ [自行管理权限概述](#prereqs-self-managed-permissions)
+ [授予管理员账户的所有用户管理所有目标账户中堆栈的权限](#stacksets-prereqs-accountsetup)
+ [为 StackSet 操作设置高级权限选项](#stacksets-prereqs-advanced-perms)
+ [设置全局键以缓解混淆代理问题](#confused-deputy-mitigation)

## 自行管理权限概述
<a name="prereqs-self-managed-permissions"></a>

必须先在各个账户中创建 IAM 服务角色，然后才能创建具有自行管理权限的 StackSet。

基本步骤如下：

1. 确定哪个 Amazon Web Services 账户是*管理员账户*。

   StackSet 是在该管理员账户中创建的。*目标账户*是在其中创建属于 StackSet 的各个堆栈的账户。

1. 确定您要如何为 StackSet 构建权限。

   利用最简单的（也是最宽松的）权限配置，您可以允许管理员账户中的*所有*用户和组创建和更新通过该账户管理的*所有* StackSet。如果您需要更精细的控制，则可设置权限以指定：
   + 哪些用户和组可在哪些目标账户中执行 StackSet 操作。
   + 用户和组可将哪些资源包含在 StackSet 中。
   + 特定用户和组可执行哪些 StackSet 操作。

1. 在管理员账户和目标账户中创建所需的 IAM 服务角色以定义所需的权限。

   具体而言，所需的两个角色是：
   + **AWSCloudFormationStackSetAdministrationRole** – 该角色将部署到管理员账户。
   + **AWSCloudFormationStackSetExecutionRole** – 该角色将部署到创建堆栈实例的所有账户。

## 授予管理员账户的所有用户管理所有目标账户中堆栈的权限
<a name="stacksets-prereqs-accountsetup"></a>

本节将介绍如何设置权限，以便管理员账户的所有用户和组在所有目标账户中执行 StackSet 操作。本节会指导您在管理员和目标账户中创建所需的 IAM 服务角色。而后，管理员账户中的任何人都可以创建、更新或删除任何目标账户中的任何堆栈。

如果以这种方式构建权限，用户在创建或更新 StackSet 时便不会传递管理员角色。

![\[在建立信任关系后，管理员账户中的任何用户都可以在目标账户中创建任何 StackSet。\]](http://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/images/stacksets_perms_master_target.png)


------
#### [ Administrator account ]

在管理员账户中，创建一个名为 **AWSCloudFormationStackSetAdministrationRole** 的 IAM 角色。

为此，您可以通过 CloudFormation 模板创建堆栈，网址为 [https://s3.amazonaws.com/cloudformation-stackset-sample-templates-us-east-1/AWSCloudFormationStackSetAdministrationRole.yml](https://s3.amazonaws.com/cloudformation-stackset-sample-templates-us-east-1/AWSCloudFormationStackSetAdministrationRole.yml)。

**Example 权限策略示例**  
前述模板创建的管理员角色包括以下权限策略：    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Action": [
        "sts:AssumeRole"
      ],
      "Resource": [
        "arn:aws:iam::*:role/AWSCloudFormationStackSetExecutionRole"
      ],
      "Effect": "Allow"
    }
  ]
}
```

**Example 示例信任策略 1**  
前述模板还包括以下信任策略，该策略授予使用管理员角色的服务权限以及附加到该角色的权限。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudformation.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

**Example 示例信任策略 2**  
要将堆栈实例部署到位于默认情况下禁用的区域中的目标账户，还需要包含该区域的区域服务主体。默认情况下禁用的每个区域都有自己的区域服务主体。  
以下示例信任策略授予在亚太地区（香港）区域 (`ap-east-1`) 使用管理员角色的服务权限，该区域在默认情况下禁用。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
            "cloudformation.amazonaws.com",
            "cloudformation.ap-east-1.amazonaws.com"
         ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
有关更多信息，请参阅 [准备在默认禁用的 Amazon Web Services 区域执行 StackSet 操作](stacksets-opt-in-regions.md)。有关区域代码的列表，请参阅*《Amazon Web Services 一般参考 Guide》*中的 [Regional endpoints](https://docs.amazonaws.cn/general/latest/gr/rande.html#regional-endpoints)。

------
#### [ Target accounts ]

在每个目标账户中，创建一个信任管理员账户的名为 **AWSCloudFormationStackSetExecutionRole** 的服务角色。该角色必须具有该确切名称。为此，您可以通过 CloudFormation 模板创建堆栈，网址为 [https://s3.amazonaws.com/cloudformation-stackset-sample-templates-us-east-1/AWSCloudFormationStackSetExecutionRole.yml](https://s3.amazonaws.com/cloudformation-stackset-sample-templates-us-east-1/AWSCloudFormationStackSetExecutionRole.yml)。当您使用此模板时，系统将提示您提供目标账户必须与其具有信任关系的管理员账户的账户 ID。

**重要**  
请注意，此模板将向管理员授予访问权限。在您使用此模板创建目标账户执行角色之后，您必须将策略声明中的权限的范围限定为您正使用堆栈集创建的资源的类型。

目标账户服务角色需要权限才能执行 CloudFormation 模板中指定的任何操作。例如，如果您的模板正在创建 S3 存储桶，则您需要权限才能为 S3 创建新对象。目标账户始终需要完整的 CloudFormation 权限，其中包含创建、更新、删除和描述堆栈的权限。

**Example 权限策略示例 1**  
此模板创建的角色将在目标账户上启用以下策略。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*"
    }
  ]
}
```

**Example 权限策略示例 2**  
以下示例显示了一个包含让堆栈集运行所需的*最低* 权限的策略声明。要在使用 CloudFormation 以外的服务资源的目标账户中创建堆栈，必须将这些服务操作和资源添加到每个目标账户的 **AWSCloudFormationStackSetExecutionRole** 策略声明中。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
         "cloudformation:*"
      ],
      "Resource": "*"
    }
  ]
}
```

**Example 示例信任策略**  
以下信任关系是由此模板创建的。管理员账户的 ID 显示为 *admin\$1account\$1id*。    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:root"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```
您可以配置现有目标账户执行角色的信任关系以信任管理员账户中的特定角色。如果您在管理员账户中删除此角色并创建一个新角色来替代它，则您必须使用新的管理员账户角色 (由上一示例中的 *admin\$1account\$1id* 表示) 配置您的目标账户信任关系。

------

## 为 StackSet 操作设置高级权限选项
<a name="stacksets-prereqs-advanced-perms"></a>

如果您需要更精细地控制用户和组通过单个管理员账户创建的 StackSet，您可以使用 IAM 角色指定：
+ 哪些用户和组可在哪些目标账户中执行 StackSet 操作。
+ 用户和组可将哪些资源包含在 StackSet 中。
+ 特定用户和组可执行哪些 StackSet 操作。

### 控制哪些用户可以在特定目标账户中执行 StackSet 操作
<a name="stacksets-prereqs-multiadmin"></a>

使用自定义管理员角色，控制哪些用户和组可以在哪些目标账户中执行 StackSet 操作。您可能希望控制管理员账户的哪些用户可以在哪些目标账户中执行 StackSet 操作。为此，您可以在每个目标账户和特定的自定义管理角色之间创建信任关系，而不是在管理员账户中创建 **AWSCloudFormationStackSetAdministrationRole** 服务角色。然后，激活特定用户和组以在特定目标账户中执行 StackSet 操作时使用自定义管理角色。

例如，您可以在管理员账户中创建角色 A 和角色 B。您可以授予角色 A 访问目标账户 1 至账户 8 的权限。您可以授予角色 B 访问目标账户 9 至账户 16 的权限。

![\[在自定义管理员角色和目标账户之间建立信任关系后，将允许用户创建 StackSet。\]](http://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/images/stacksets_perms_admin_target.png)


设置必要的权限包括定义自定义管理员角色、为目标账户创建服务角色并授予用户在执行 StackSet 操作时传递自定义管理员角色的权限。

一般而言，下面是具有必要权限后的工作原理：在创建 StackSet 时，用户必须指定自定义管理员角色。用户必须具有将角色传递到 CloudFormation 的权限。此外，自定义管理员角色还必须与为 StackSet 指定的目标账户具有信任关系。CloudFormation 会创建 StackSet 并将自定义管理员角色与其关联。在更新 StackSet 时，用户必须明确指定自定义管理员角色，即使它与之前用于此 StackSet 的自定义管理员角色相同，也是如此。CloudFormation 根据上述要求使用该角色来更新堆栈。

------
#### [ Administrator account ]

**Example 权限策略示例**  
对于每个 StackSet，创建一个自定义管理员角色，该角色具有担任目标账户执行角色的权限。  
每个目标账户中的目标账户执行角色名称必须相同。如果角色名称为 **AWSCloudFormationStackSetExecutionRole**，StackSets 会在创建 StackSet 时会自动使用该名称。如果指定自定义角色名称，则用户在创建 StackSet 时必须提供执行角色名称。  
使用以下权限策略，创建具有自定义名称的 [IAM 服务角色](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_create_for-service.html)：在以下示例中，*custom\$1execution\$1role* 是指目标账户中的执行角色。    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/custom_execution_role"
            ],
            "Effect": "Allow"
        }
    ]
}
```
要在单个语句中指定多个账户，请使用逗号将其隔开。  

```
"Resource": [
  "arn:aws:iam::target_account_id_1:role/custom_execution_role", 
  "arn:aws:iam::target_account_id_2:role/custom_execution_role"
]
```
您可以通过使用通配符 (\$1) 而不是账户 ID，指定所有目标账户。  

```
"Resource": [
  "arn:aws:iam::*:role/custom_execution_role"
]
```

**Example 示例信任策略 1**  
您必须为服务角色提供信任策略，从而定义哪些 IAM 主体可以担任该角色。    
****  

```
{ 
  "Version":"2012-10-17",		 	 	  
  "Statement": [ 
    { 
      "Effect": "Allow", 
      "Principal": { 
        "Service": "cloudformation.amazonaws.com" 
      }, 
      "Action": "sts:AssumeRole" 
    } 
  ] 
}
```

**Example 示例信任策略 2**  
要将堆栈实例部署到位于默认情况下禁用的区域中的目标账户，还需要包含该区域的区域服务主体。默认情况下禁用的每个区域都有自己的区域服务主体。  
以下示例信任策略授予在亚太地区（香港）区域 (`ap-east-1`) 使用管理员角色的服务权限，该区域在默认情况下禁用。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
            "cloudformation.amazonaws.com",
            "cloudformation.ap-east-1.amazonaws.com"
         ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
有关更多信息，请参阅 [准备在默认禁用的 Amazon Web Services 区域执行 StackSet 操作](stacksets-opt-in-regions.md)。有关区域代码列表，请参阅《Amazon General Reference Guide**》中的 [Regional endpoints](https://docs.amazonaws.cn/general/latest/gr/rande.html#regional-endpoints)。

**Example 示例传递角色策略**  
您还需要为 IAM 用户提供 IAM 权限策略，允许该用户在执行 StackSet 操作时传递自定义管理员角色。有关更多信息，请参阅[向用户授予将角色传递给 Amazon 服务的权限](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_use_passrole.html)。  
在以下示例中，*customized\$1admin\$1role* 是指用户需要传递的管理员角色。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:GetRole",
        "iam:PassRole"
      ],
      "Resource": "arn:aws:iam::*:role/customized_admin_role"
    }
  ]
}
```

------
#### [ Target accounts ]

在每个目标账户中，创建一个服务角色，该角色信任要用于此账户的自定义管理员角色。

目标账户角色需要权限才能执行 CloudFormation 模板中指定的任何操作。例如，如果您的模板正在创建 S3 存储桶，则您需要在 S3 中创建新对象的权限。目标账户始终需要完整的 CloudFormation 权限，其中包含创建、更新、删除和描述堆栈的权限。

每个目标账户中的目标账户角色名称必须相同。如果角色名称为 **AWSCloudFormationStackSetExecutionRole**，StackSets 会在创建 StackSet 时会自动使用该名称。如果指定自定义角色名称，则用户在创建 StackSet 时必须提供执行角色名称。

**Example 权限策略示例**  
以下示例显示了一个包含让堆栈集运行所需的*最低* 权限的策略声明。要在使用非 CloudFormation 服务资源的目标账户中创建堆栈，必须将这些服务操作和资源添加到权限策略。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:*"
      ],
      "Resource": "*"
    }
  ]
}
```

**Example 示例信任策略**  
在创建角色以定义信任关系时，必须提供以下信任策略：    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:role/customized_admin_role"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

------

### 控制用户可以在特定 StackSet 中包含哪些资源
<a name="stacksets-prereqs-executionrole"></a>

使用自定义执行角色可以控制用户和组可将哪些堆栈资源包含在 StackSet 中。例如，您可能希望设置一个组，该组只能将与 Amazon S3 相关的资源包含在他们创建的 StackSet 中，而另一个团队只能包含 DynamoDB 资源。为此，您可以在每个组的自定义管理员角色与每组资源的自定义执行角色之间建立信任关系。自定义执行角色定义可将哪些堆栈资源包含在 StackSet 中。自定义管理员角色位于管理员账户中，而自定义执行角色位于每个目标账户（要在其中使用定义的资源创建 StackSet 的账户）中。然后，激活特定用户和组以在执行 StackSet 操作时使用自定义管理角色。

例如，您可以在管理员账户中创建自定义管理员角色 A、B 和 C。有权使用角色 A 的用户和组可以创建相应的 StackSet，这些 StackSet 包含自定义执行角色 X 中专门列出的堆栈资源，而不包含角色 Y 或 Z 中的堆栈资源或任何执行角色中未包含的资源。

![\[在自定义管理员角色和目标账户中的自定义执行角色之间建立信任关系后，将允许用户创建 StackSet。\]](http://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/images/stacksets_perms_admin_execution.png)


在更新 StackSet 时，用户必须明确指定自定义管理员角色，即使它与之前用于此 StackSet 的自定义管理员角色相同，也是如此。只要用户具有对该 StackSet 执行操作的权限，CloudFormation 就会使用指定的自定义管理员角色执行更新。

同样，用户还可以指定自定义的执行角色。如果用户指定了自定义执行角色，CloudFormation 将根据上述要求使用该角色来更新堆栈。如果用户未指定自定义执行角色，CloudFormation 将使用以前与 StackSet 关联的自定义执行角色来执行更新，只要用户具有对该 StackSet 执行操作的权限。

------
#### [ Administrator account ]

在管理员账户中创建自定义管理员角色，如 [控制哪些用户可以在特定目标账户中执行 StackSet 操作](#stacksets-prereqs-multiadmin) 中所述。包含自定义管理员角色和希望该角色使用的自定义执行角色之间的信任关系。

**Example 权限策略示例**  
以下示例是针对为目标账户定义的 **AWSCloudFormationStackSetExecutionRole** 以及自定义执行角色的权限策略。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
   "Statement": [
    {
      "Sid": "Stmt1487980684000",
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole" 
      ],
      "Resource": [ 
        "arn:aws:iam::*:role/AWSCloudFormationStackSetExecutionRole",
        "arn:aws:iam::*:role/custom_execution_role" 
      ]
    } 
  ]
}
```

------
#### [ Target accounts ]

在要在其中创建 StackSet 的目标账户中，创建一个自定义的执行角色，该角色授予对您要用户和组能够将其包含在 StackSet 中的服务和资源的权限。

**Example 权限策略示例**  
以下示例提供了 StackSet 的最小权限以及创建 Amazon DynamoDB 表的权限。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:*"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamoDb:createTable"
      ],
      "Resource": "*"
    }
  ]
}
```

**Example 示例信任策略**  
在创建角色以定义信任关系时，必须提供以下信任策略：    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:role/customized_admin_role"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

------

### 为特定 StackSet 操作设置权限
<a name="stacksets-prereqs-iam-actions"></a>

此外，您可以为能够执行特定的 StackSet 操作（例如，创建、更新或删除 StackSet 或堆栈实例）的用户和组设置权限。有关更多信息，请参阅*《服务授权参考》*中的 [CloudFormation 的操作、资源和条件键](https://docs.amazonaws.cn/service-authorization/latest/reference/list_awscloudformation.html)。

## 设置全局键以缓解混淆代理问题
<a name="confused-deputy-mitigation"></a>

混淆代理问题是一个安全性问题，即不具有某操作执行权限的实体可能会迫使具有更高权限的实体执行该操作。在 Amazon 中，跨服务模拟可能会导致混淆代理问题。一个服务（*呼叫服务*) 调用另一项服务（*所谓的服务*)时，可能会发生跨服务模拟。可以操纵调用服务以使用其权限对另一个客户的资源进行操作，否则该服务不应有访问权限。为了防止这种情况，Amazon 提供可帮助您保护所有服务的服务委托人数据的工具，这些服务委托人有权限访问账户中的资源。

建议在资源策略中使用 [https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) 和 [https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) 全局条件上下文键，以限制 Amazon CloudFormation StackSets 为其他服务提供的资源访问权限。如果使用两个全局条件上下文键，在同一策略语句中使用时，`aws:SourceAccount` 值和 `aws:SourceArn` 值中的账户必须使用相同的账户 ID。

防范混淆代理问题最有效的方法是使用 `aws:SourceArn` 全局条件上下文键和资源的完整 ARN。如果不知道资源的完整 ARN，或者正在指定多个资源，请针对 ARN 未知部分使用带有通配符（`*`）的 `aws:SourceArn` 全局上下文条件键。例如 `arn:aws:cloudformation::123456789012:*`。请尽可能使用 `aws:SourceArn`，因为它更具体。仅当无法确定正确的 ARN 或 ARN 模式时使用 `aws:SourceAccount`。

当 StackSets 在**管理员**账户中担任**管理**角色时，StackSets 会填充**管理员**账户 ID 和 StackSets Amazon 资源名称（ARN）。因此，您可以在信任关系中为[全局键](https://docs.amazonaws.cn/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) `aws:SourceAccount` 和 `aws:SourceArn` 定义条件，以防止[混淆代理问题](https://docs.amazonaws.cn/IAM/latest/UserGuide/confused-deputy.html)。以下示例演示如何使用 StackSets 中的 `aws:SourceArn` 和 `aws:SourceAccount` 全局条件上下文键来防范混淆代理问题。

------
#### [ Administrator account ]

**Example `aws:SourceAccount` 和 `aws:SourceArn` 的全局键示例**  
使用 StackSets 时，请在 **AWSCloudFormationStackSetAdministrationRole** 信任策略中定义全局键 `aws:SourceAccount` 和 `aws:SourceArn` 以防出现混淆代理问题。    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudformation.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "111122223333"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:cloudformation:*:111122223333:stackset/*"
        }
      }
    }
  ]
}
```

**Example StackSets ARN**  
指定关联的 StackSets ARN 以进行更精细的控制。    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudformation.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "111122223333",
                    "aws:SourceArn": [
                        "arn:aws:cloudformation:STACKSETS-REGION:111122223333:stackset/STACK-SET-ID-1",
                        "arn:aws:cloudformation:STACKSETS-REGION:111122223333:stackset/STACK-SET-ID-2"
                    ]
                }
            }
        }
    ]
}
```

------