

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

# 为 Amazon S3 来源创建 EventBridge 规则（Amazon CloudFormation 模板）
<a name="create-cloudtrail-S3-source-cfn"></a>

 Amazon CloudFormation 要使用创建规则，请更新您的模板，如下所示。<a name="proc-cfn-event-s3-createrule"></a>

**创建以 Amazon S3 作为事件源和 CodePipeline 目标的 EventBridge 规则并应用权限策略**

1. 在模板下的模板中`Resources`，使用`AWS::IAM::Role` Amazon CloudFormation 资源配置允许您的事件启动管道的 IAM 角色。此条目将创建一个使用两个策略的角色：
   + 第一个策略允许代入角色。
   + 第二个策略提供启动管道所需的权限。

   **我为何做出此更改？** 添加`AWS::IAM::Role`资源可以 Amazon CloudFormation 为创建权限 EventBridge。此资源已添加到您的 Amazon CloudFormation 堆栈中。

------
#### [ YAML ]

   ```
     EventRole:
       Type: AWS::IAM::Role
       Properties:
         AssumeRolePolicyDocument:
           Version: 2012-10-17		 	 	 
           Statement:
             -
               Effect: Allow
               Principal:
                 Service:
                   - events.amazonaws.com
               Action: sts:AssumeRole
         Path: /
         Policies:
           -
             PolicyName: eb-pipeline-execution
             PolicyDocument:
               Version: 2012-10-17		 	 	 
               Statement:
                 -
                   Effect: Allow
                   Action: codepipeline:StartPipelineExecution
                   Resource: !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ]
   
   
   ...
   ```

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

   ```
     "EventRole": {
       "Type": "AWS::IAM::Role",
       "Properties": {
         "AssumeRolePolicyDocument": {
           "Version": "2012-10-17",		 	 	 
           "Statement": [
             {
               "Effect": "Allow",
               "Principal": {
                 "Service": [
                   "events.amazonaws.com"
                 ]
               },
               "Action": "sts:AssumeRole"
             }
           ]
         },
         "Path": "/",
         "Policies": [
           {
             "PolicyName": "eb-pipeline-execution",
             "PolicyDocument": {
               "Version": "2012-10-17",		 	 	 
               "Statement": [
                 {
                   "Effect": "Allow",
                   "Action": "codepipeline:StartPipelineExecution",
                   "Resource": {
                     "Fn::Join": [
                       "",
                       [
                         "arn:aws:codepipeline:",
                         {
                           "Ref": "AWS::Region"
                         },
                         ":",
                         {
                           "Ref": "AWS::AccountId"
                         },
                         ":",
                         {
                           "Ref": "AppPipeline"
                         }
                       ]
                     ]
   
   ...
   ```

------

1. 使用`AWS::Events::Rule` Amazon CloudFormation 资源添加 EventBridge 规则。此事件模式会创建一个事件，以监控 Amazon S3 源桶上的 `CopyObject`、`PutObject` 和 `CompleteMultipartUpload`。此外，还包括您管道的目标。当发生 `CopyObject`、`PutObject` 或 `CompleteMultipartUpload` 时，此规则将对目标管道调用 `StartPipelineExecution`。

   **我为何做出此更改？** 添加`AWS::Events::Rule`资源 Amazon CloudFormation 即可创建事件。此资源已添加到您的 Amazon CloudFormation 堆栈中。

------
#### [ YAML ]

   ```
     EventRule:
       Type: AWS::Events::Rule
       Properties:
         EventPattern:
           source:
             - aws.s3
           detail-type:
             - 'AWS API Call via CloudTrail'
           detail:
             eventSource:
               - s3.amazonaws.com
             eventName:
               - CopyObject
               - PutObject
               - CompleteMultipartUpload
             requestParameters:
               bucketName:
                 - !Ref SourceBucket
               key:
                 - !Ref SourceObjectKey
         Targets:
           -
             Arn:
               !Join [ '', [ 'arn:aws:codepipeline:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref AppPipeline ] ]
             RoleArn: !GetAtt EventRole.Arn
             Id: codepipeline-AppPipeline
   
   
   ...
   ```

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

   ```
     "EventRule": {
       "Type": "AWS::Events::Rule",
       "Properties": {
         "EventPattern": {
           "source": [
             "aws.s3"
           ],
           "detail-type": [
             "AWS API Call via CloudTrail"
           ],
           "detail": {
             "eventSource": [
               "s3.amazonaws.com"
             ],
             "eventName": [
               "CopyObject",
               "PutObject",
               "CompleteMultipartUpload"
             ],
             "requestParameters": {
               "bucketName": [
                 {
                   "Ref": "SourceBucket"
                 }
               ],
               "key": [
                 {
                   "Ref": "SourceObjectKey"
                 }
               ]
             }
           }
         },
         "Targets": [
           {
             "Arn": {
               "Fn::Join": [
                 "",
                 [
                   "arn:aws:codepipeline:",
                   {
                     "Ref": "AWS::Region"
                   },
                   ":",
                   {
                     "Ref": "AWS::AccountId"
                   },
                   ":",
                   {
                     "Ref": "AppPipeline"
                   }
                 ]
               ]
             },
             "RoleArn": {
               "Fn::GetAtt": [
                 "EventRole",
                 "Arn"
               ]
             },
             "Id": "codepipeline-AppPipeline"
           }
         ]
       }
     }
   },
   
   ...
   ```

------

1. 将此代码段添加到第一个模板，以允许跨堆栈功能：

------
#### [ YAML ]

   ```
   Outputs:
     SourceBucketARN:
       Description: "S3 bucket ARN that Cloudtrail will use"
       Value: !GetAtt SourceBucket.Arn
       Export:
         Name: SourceBucketARN
   ```

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

   ```
     "Outputs" : {
       "SourceBucketARN" : {
         "Description" : "S3 bucket ARN that Cloudtrail will use",
         "Value" : { "Fn::GetAtt": ["SourceBucket", "Arn"] },
         "Export" : {
           "Name" : "SourceBucketARN"
         }
       }
   
   ...
   ```

------

1. （可选）要为特定映像 ID 配置具有源覆盖的输入转换器，请使用以下 YAML 片段：以下示例配置了覆盖，其中：
   + `actionName`，本示例中的 `Source`，是在创建管道时定义的动态值，不是从源事件派生的。
   + `revisionType`，本示例中的 `S3_OBJECT_VERSION_ID`，是在创建管道时定义的动态值，不是从源事件派生的。
   + 在本示例中`revisionValue`，< *revisionValue* > 是从源事件变量派生的。

   ```
   ---
   Rule: my-rule
   Targets:
   - Id: MyTargetId
     Arn: pipeline-ARN
     InputTransformer:
       InputPathsMap:
         revisionValue: "$.detail.object.version-id"
       InputTemplate:
         sourceRevisions:
           actionName: Source
           revisionType: S3_OBJECT_VERSION_ID
           revisionValue: '<revisionValue>'
   ```

1. 将更新后的模板保存到本地计算机上，然后打开 Amazon CloudFormation 控制台。

1. 选择堆栈，然后选择**为当前堆栈创建更改集**。

1. 上传更新的模板，然后查看 Amazon CloudFormation中所列的更改。以下是将对堆栈进行的更改。您应在列表中看到新资源。

1. 选择**执行**。<a name="proc-cfn-flag-s3"></a>

**编辑管道的 PollForSourceChanges 参数**
**重要**  
使用此方法创建管道时，如果 `PollForSourceChanges` 参数未明确设置为 false，则默认为 true。添加基于事件的更改检测时，必须将参数添加到输出并将其设置为 false 以禁用轮询。否则，您的管道将针对单个源更改启动两次。有关更多信息，请参阅 [`PollForSourceChanges` 参数的有效设置](PollForSourceChanges-defaults.md)。
+ 在模板中，将 `PollForSourceChanges` 更改为 `false`。如果您未在管道定义中包含 `PollForSourceChanges`，请添加它并将它设置为 `false`。

  **我为何做出此更改？** 将 `PollForSourceChanges` 更改为 `false` 将关闭定期检查，因此您只能使用基于事件的更改检测。

------
#### [ YAML ]

  ```
            Name: Source
            Actions: 
              - 
                Name: SourceAction
                ActionTypeId: 
                  Category: Source
                  Owner: AWS
                  Version: 1
                  Provider: S3
                OutputArtifacts: 
                  - Name: SourceOutput
                Configuration: 
                  S3Bucket: !Ref SourceBucket
                  S3ObjectKey: !Ref SourceObjectKey
                  PollForSourceChanges: false
                RunOrder: 1
  ```

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

  ```
   {
      "Name": "SourceAction",
      "ActionTypeId": {
        "Category": "Source",
        "Owner": "AWS",
        "Version": 1,
        "Provider": "S3"
      },
      "OutputArtifacts": [
        {
          "Name": "SourceOutput"
        }
      ],
      "Configuration": {
        "S3Bucket": {
          "Ref": "SourceBucket"
        },
        "S3ObjectKey": {
          "Ref": "SourceObjectKey"
        },
        "PollForSourceChanges": false
      },
      "RunOrder": 1
    }
  ```

------<a name="proc-cfn-event-s3-createtrail"></a>

**为您的 Amazon S3 管道的 CloudTrail 资源创建第二个模板**
+ 在单独的模板中`Resources`，使用`AWS::S3::Bucket``AWS::S3::BucketPolicy`、和`AWS::CloudTrail::Trail` Amazon CloudFormation 资源为其提供简单的存储桶定义和跟踪 CloudTrail。

  **我为何做出此更改？** 鉴于当前每个账户只能有五条 CloudTrail 跟踪，因此必须单独创建和管理跟踪。（参见[中的限制 Amazon CloudTrail](https://docs.amazonaws.cn/awscloudtrail/latest/userguide/WhatIsCloudTrail-Limits.html)。） 但是，您可以在单个跟踪上包括许多 Amazon S3 桶，因此您可以创建跟踪一次，然后根据需要为其他管道添加 Amazon S3 桶。将以下内容粘贴到第二个示例模板文件中。

------
#### [ YAML ]

  ```
  ###################################################################################
  # Prerequisites: 
  #   - S3 SourceBucket and SourceObjectKey must exist
  ###################################################################################
  
  Parameters:
    SourceObjectKey:
      Description: 'S3 source artifact'
      Type: String
      Default: SampleApp_Linux.zip
  
  Resources:
    AWSCloudTrailBucketPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:
        Bucket: !Ref AWSCloudTrailBucket
        PolicyDocument:
          Version: 2012-10-17		 	 	 
          Statement:
            -
              Sid: AWSCloudTrailAclCheck
              Effect: Allow
              Principal:
                Service:
                  - cloudtrail.amazonaws.com
              Action: s3:GetBucketAcl
              Resource: !GetAtt AWSCloudTrailBucket.Arn
            -
              Sid: AWSCloudTrailWrite
              Effect: Allow
              Principal:
                Service:
                  - cloudtrail.amazonaws.com
              Action: s3:PutObject
              Resource: !Join [ '', [ !GetAtt AWSCloudTrailBucket.Arn, '/AWSLogs/', !Ref 'AWS::AccountId', '/*' ] ]
              Condition: 
                StringEquals:
                  s3:x-amz-acl: bucket-owner-full-control
    AWSCloudTrailBucket:
      Type: AWS::S3::Bucket
      DeletionPolicy: Retain
    AwsCloudTrail:
      DependsOn:
        - AWSCloudTrailBucketPolicy
      Type: AWS::CloudTrail::Trail
      Properties:
        S3BucketName: !Ref AWSCloudTrailBucket
        EventSelectors:
          -
            DataResources:
              -
                Type: AWS::S3::Object
                Values:
                  - !Join [ '', [ !ImportValue SourceBucketARN, '/', !Ref SourceObjectKey ] ]
            ReadWriteType: WriteOnly
            IncludeManagementEvents: false
        IncludeGlobalServiceEvents: true
        IsLogging: true
        IsMultiRegionTrail: true
  
  
  ...
  ```

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

  ```
  {
    "Parameters": {
      "SourceObjectKey": {
        "Description": "S3 source artifact",
        "Type": "String",
        "Default": "SampleApp_Linux.zip"
      }
    },
    "Resources": {
      "AWSCloudTrailBucket": {
        "Type": "AWS::S3::Bucket",
          "DeletionPolicy": "Retain"
      },
      "AWSCloudTrailBucketPolicy": {
        "Type": "AWS::S3::BucketPolicy",
        "Properties": {
          "Bucket": {
            "Ref": "AWSCloudTrailBucket"
          },
          "PolicyDocument": {
            "Version": "2012-10-17",		 	 	 
            "Statement": [
              {
                "Sid": "AWSCloudTrailAclCheck",
                "Effect": "Allow",
                "Principal": {
                  "Service": [
                    "cloudtrail.amazonaws.com"
                  ]
                },
                "Action": "s3:GetBucketAcl",
                "Resource": {
                  "Fn::GetAtt": [
                    "AWSCloudTrailBucket",
                    "Arn"
                  ]
                }
              },
              {
                "Sid": "AWSCloudTrailWrite",
                "Effect": "Allow",
                "Principal": {
                  "Service": [
                    "cloudtrail.amazonaws.com"
                  ]
                },
                "Action": "s3:PutObject",
                "Resource": {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "AWSCloudTrailBucket",
                          "Arn"
                        ]
                      },
                      "/AWSLogs/",
                      {
                        "Ref": "AWS::AccountId"
                      },
                      "/*"
                    ]
                  ]
                },
                "Condition": {
                  "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                  }
                }
              }
            ]
          }
        }
      },
      "AwsCloudTrail": {
        "DependsOn": [
          "AWSCloudTrailBucketPolicy"
        ],
        "Type": "AWS::CloudTrail::Trail",
        "Properties": {
          "S3BucketName": {
            "Ref": "AWSCloudTrailBucket"
          },
          "EventSelectors": [
            {
              "DataResources": [
                {
                  "Type": "AWS::S3::Object",
                  "Values": [
                    {
                      "Fn::Join": [
                        "",
                        [
                          {
                            "Fn::ImportValue": "SourceBucketARN"
                          },
                          "/",
                          {
                            "Ref": "SourceObjectKey"
                          }
                        ]
                      ]
                    }
                  ]
                }
              ],
              "ReadWriteType": "WriteOnly",
              "IncludeManagementEvents": false
            }
          ],
          "IncludeGlobalServiceEvents": true,
          "IsLogging": true,
          "IsMultiRegionTrail": true
        }
      }
    }
  }
  
  ...
  ```

------