

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

# 构建您自己的自定义
<a name="cfcn-byo-customizations"></a>

要构建自己的自定义项，您可以通过添加或更新服务控制策略 (SCPs)、资源控制策略 (RCPs) 和 CloudFormation 资源来修改 cfcT `manifest.yaml` 文件。对于必须部署的资源，您可以添加或删除帐户和 OUs。您可以添加或修改包文件夹中的模板，创建自己的文件夹，并引用 `manifest.yaml` 文件中的模板或文件夹。

本部分介绍构建自己的自定义的两个主要部分：
+ 如何为服务控制策略设置自己的配置包
+ 如何为堆 AWS CloudFormation 栈集设置自己的配置包

# 为 SCPs 或设置配置包 RCPs
<a name="cfcn-set-up-custom-scps"></a>

本节介绍如何为服务控制策略 (SCPs) 或资源控制策略 (RCPs) 创建配置包。此过程的两个主要部分是（1）准备 CfCT 清单文件，以及（2）准备您的文件夹结构。

## 步骤 1：编辑 manifest.yaml 文件
<a name="cfct-byo-scp-step-1"></a>

使用示例 `manifest.yaml` 文件作为起点。输入所有必要的配置。添加 `resource_file` 和 `deployment_targets` 详细信息。

以下代码段显示了默认清单文件。

```
---
region: us-east-1
version: 2021-03-15

resources: []
```

`region` 的值将在部署期间自动添加。它必须与您在其中部署 CfCT 的区域匹配。此区域必须与 AWS Control Tower 区域相同。

要在 Amazon S3 存储桶中存储的 zip 包中的 `example-configuration` 文件夹中添加自定义 SCP 或 RCP，请打开 `example-manifest.yaml` 文件并开始编辑。

```
---
region: your-home-region
version: 2021-03-15

resources:
  - name: test-preventive-controls
    description: To prevent from deleting or disabling resources in member accounts
    resource_file: policies/preventive-controls.json
    deploy_method: scp | rcp
    #Apply to the following OU(s)
    deployment_targets:
      organizational_units: #array of strings
        - OUName1
        - OUName2 

…truncated…
```

以下代码段显示了示例自定义清单文件。您可以通过一次更改添加多个策略。

```
---
region: us-east-1
version: 2021-03-15

resources:
  - name: block-s3-public-access
    description: To S3 buckets to have public access
    resource_file: policies/block-s3-public.json
    deploy_method: scp | rcp
    #Apply to the following OU(s)
    deployment_targets:
      organizational_units: #array of strings
        - OUName1
        - OUName2
```

## 步骤 2：创建文件夹结构
<a name="cfct-byo-scp-step-2"></a>

如果您使用的是 Amazon S3 URL 作为资源文件并使用 key/value 成对的**参数**，则可以跳过此步骤。

您必须包含 JSON 格式的 SCP 策略或 RCP 策略才能支持清单文件，因为清单文件会引用 JSON 文件。确保文件路径与清单文件中提供的路径信息相匹配。
+ *策略* JSON 文件包含 RCPs 要部署到的 SCPs 或 OUs。

以下代码段显示了示例清单文件的文件夹结构。

```
- manifest.yaml
- policies/
   - block-s3-public.json
```

以下代码段是示例 `block-s3-public.json` 策略文件。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Sid":"GuardPutAccountPublicAccessBlock",
         "Effect":"Deny",
         "Action":"s3:PutAccountPublicAccessBlock",
         "Resource":"arn:aws:s3:::*"
      }
   ]
}
```

------

# 为以下各项设置配置包 CloudFormation StackSets
<a name="cfcn-byo-cfn-stacksets"></a>

本节介绍如何为设置配置包 CloudFormation StackSets。此过程的两个主要部分是（1）准备清单文件，以及（2）更新文件夹结构。

## 步骤 1：编辑现有清单文件
<a name="cfcn-byo-cfn-stacksets-step-1"></a>

将新 CloudFormation StackSets 信息添加到您之前编辑的清单文件中。

为了便于查看，以下代码段包含的自定义清单文件与之前为 SCPs 或 RCPs设置配置包时显示的相同。现在，您可以进一步编辑此文件，以包含有关您的资源的详细信息。

```
---
region: us-east-1
version: 2021-03-15

resources:
  
  - name: block-s3-public-access
    description: To S3 buckets to have public access
    resource_file: policies/block-s3-public.json
    deploy_method: scp | rcp
    #Apply to the following OU(s)
    deployment_targets:
    organizational_units: #array of strings
    - OUName1
    - OUName2
```

以下代码段显示了包含 `resources` 详细信息的经编辑的示例清单文件。`resources` 的顺序决定了创建 `resources` 依赖关系的执行顺序。您可以根据业务需求编辑以下示例清单文件。

```
---
region: your-home-region
version: 2021-03-15

…truncated…

resources:
  - name: stackset-1
    resource_file: templates/create-ssm-parameter-keys-1.template
    parameters:
      - parameter_key: parameter-1
        parameter_value: value-1
    deploy_method: stack_set
    deployment_targets:
      accounts: # array of strings, [0-9]{12}
        - account number or account name
        - 123456789123
      organizational_units: #array of strings, ou ids, ou-xxxx
        - OuName1
        - OUName2 
    export_outputs:
      - name: /org/member/test-ssm/app-id
        value: $[output_ApplicationId]
    regions:
      - region-name

  - name: stackset-2
    resource_file: s3://bucket-name/key-name
    parameters:
      - parameter_key: parameter-1
        parameter_value: value-1
    deploy_method: stack_set
    deployment_targets:
      accounts: # array of strings, [0-9]{12}
        - account number or account name
        - 123456789123
      organizational_units: #array of strings
        - OuName1
        - OUName2 
regions:
  - region-name
```

以下示例显示您可以在清单文件中添加多个 CloudFormation 资源。

```
---
region: us-east-1
version: 2021-03-15

resources:
  - name: block-s3-public-access
    description: To S3 buckets to have public access
    resource_file: policies/block-s3-public.json
    deploy_method: scp | rcp
    #Apply to the following OU(s)
    deployment_targets:
      organizational_units: #array of strings
        - Custom
        - Sandbox

  - name: transit-network
    resource_file: templates/transit-gateway.template
    parameter_file: parameters/transit-gateway.json
    deploy_method: stack_set
    deployment_targets:
      accounts: # array of strings, [0-9]{12}
        - Prod
        - 123456789123 #Network
      organizational_units: #array of strings
        - Custom
    export_outputs:
      - name: /org/network/transit-gateway-id
        value: $[output_TransitGatewayID]
    regions:
      - us-east-1
```

## 步骤 2：更新文件夹结构
<a name="cfct-byo-cfn-stacksets-step-2"></a>

更新文件夹结构时，可以在清单文件中包含所有支持的 CloudFormation 模板文件以及 SCP 或 RCP 策略文件。验证文件路径是否与清单文件中提供的路径相匹配。
+ *模板*文件包含要部署的 AWS 资源 OUs 和帐户。
+ *policy* 文件包含模板文件中使用的输入参数。

以下示例显示了在[步骤 1](#cfcn-byo-cfn-stacksets-step-1) 中创建的示例清单文件的文件夹结构。

```
- manifest.yaml
- policies/
   - block-s3-public.json
- templates/
   - transit-gateway.template
```

# “alfred” 助手和 CloudFormation 参数文件
<a name="alfred-helper"></a>

 cfCT 为你提供了一种名为 *alfred* helper 的机制，用于获取模板中定义的 [SSM 参数存储](https://docs.aws.amazon.com//systems-manager/latest/userguide/systems-manager-parameter-store.html)密钥的值。 CloudFormation 使用 *alfred* 助手，您可以使用存储在 SSM 参数存储中的值，而无需更新模板。 CloudFormation 有关更多信息，请参阅[什么是 CloudFormation 模板？](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/gettingstarted.templatebasics.html#gettingstarted.templatebasics.what) 在《*CloudFormation 用户指南》*中。

**重要**  
 *alfred* 助手有两个限制。参数仅在 AWS Control Tower 管理账户的主区域中可用。作为最佳实践，可以考虑使用堆栈实例之间不会发生变化的值。当“alfred”助手检索参数时，它会从导出该变量的堆栈集中随机选择一个堆栈实例。

## 示例
<a name="w2aac28c41c15c13b7"></a>

 假设你有两个 CloudFormation 堆栈集。*堆栈集 1* 有一个堆栈实例，可部署到一个区域中的一个账户。它在可用区中创建 Amazon VPC 和子网，并且 `VPC ID` 和 `subnet ID` 必须作为参数值传递到*堆栈集 2* 中。在可将 `VPC ID` 和 `subnet ID` 传递到*堆栈集 2* 中之前，必须使用 `AWS:::SSM::Parameter` 将 `VPC ID` 和 `subnet ID` 存储在*堆栈集 1* 中。有关更多信息，请参阅《CloudFormation 用户指南》**中的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html)。

**CloudFormation 堆栈集 1：**

 在以下片段中，*alfred* 助手可以`subnet ID`从参数存储中获取`VPC ID`和的值，并将它们作为输入传递给 StackSet 状态机。

```
VpcIdParameter:
    Type: AWS::SSM::Parameter
    Properties:
      Name: '/stack_1/vpc/id'
      Description: Contains the VPC id
      Type: String
      Value: !Ref MyVpc

SubnetIdParameter:
    Type: AWS::SSM::Parameter
    Properties:
      Name: '/stack_1/subnet/id'
      Description: Contains the subnet id
      Type: String
      Value: !Ref MySubnet
```

**CloudFormation 堆栈集 2：**

 该片段显示了 CloudFormation stack 2 `manifest.yaml` 文件中指定的参数。

```
parameters:
      - parameter_key: VpcId
        parameter_value: $[alfred_ssm_/stack_1/vpc/id]
      - parameter_key: SubnetId
        parameter_value: $[alfred_ssm_/stack_1/subnet/id]
```

**CloudFormation 堆栈集 2.1：**

 该片段显示您可以列出`alfred_ssm`属性以支持类型*CommaDelimitedList*参数。有关更多信息，请参阅《CloudFormation 用户指南》**中的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#parameters-section-structure-properties-type](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#parameters-section-structure-properties-type)。

```
parameters:
      - parameter_key: VpcId # Type: String
        parameter_value: $[alfred_ssm_/stack_1/vpc/id']
      - parameter_key: SubnetId # Type: String
        parameter_value: $[ alfred_ssm_/stack_1/subnet/id']
      - parameter_key: AvailablityZones # Type: CommaDelimitedList
        parameter_value:   - "$[alfred_ssm_/availability_zone_1]"  - "$[alfred_ssm_/availability_zone_2]"
```

**自定义包的 JSON 架构**  
cfcT 定制包的 JSON 架构位于[上的 GitHub源代码存储库](https://github.com/aws-solutions/aws-control-tower-customizations)中。您可以将该架构与许多您最喜欢的开发工具一起使用，而且您可能会发现，在构建自己的 CfCT `manifest.yaml` 文件时，该架构有助于减少错误。