

# Connecting to Amazon S3 source actions that use EventBridge and AWS CloudTrail
<a name="create-cloudtrail-S3-source"></a>

The instructions in this section provide the steps for creating the S3 source action that uses AWS CloudTrail resources that you must create and manage. To use the S3 source action with EventBridge that does not require additional AWS CloudTrail resources, use the CLI instructions at [Migrate polling pipelines with an S3 source enabled for events](update-change-detection.md#update-change-detection-S3-event).

**Important**  
This procedure provides the steps for creating the S3 source action that uses AWS CloudTrail resources that you must create and manage. The procedure to create this action without AWS CloudTrail resources is not available in the console. To use the CLI, see [Migrate polling pipelines with an S3 source enabled for events](update-change-detection.md#update-change-detection-S3-event).

To add an Amazon S3 source action in CodePipeline, you choose either to: 
+ Use the CodePipeline console **Create pipeline** wizard ([Create a custom pipeline (console)](pipelines-create.md#pipelines-create-console)) or **Edit action** page to choose the **S3** provider option. The console creates an EventBridge rule and a CloudTrail trail that starts your pipeline when the source changes.
+ Use the AWS CLI to add the action configuration for the `S3` action and create additional resources as follows:
  + Use the `S3` example action configuration in [Amazon S3 source action reference](action-reference-S3.md) to create your action as shown in [Create a pipeline (CLI)](pipelines-create.md#pipelines-create-cli).
  + The change detection method defaults to starting the pipeline by polling the source. You should disable periodic checks and create the change detection rule and trail manually. Use one of the following methods: [Create an EventBridge rule for an Amazon S3 source (console)](create-cloudtrail-S3-source-console.md), [Create an EventBridge rule for an Amazon S3 source (CLI)](create-cloudtrail-S3-source-cli.md), or [Create an EventBridge rule for an Amazon S3 source (CloudFormation template)](create-cloudtrail-S3-source-cfn.md).

AWS CloudTrail is a service that logs and filters events on your Amazon S3 source bucket. The trail sends the filtered source changes to the EventBridge rule. The EventBridge rule detects the source change and then starts your pipeline. 

**Requirements:**
+ If you are not creating a trail, use an existing AWS CloudTrail trail for logging events in your Amazon S3 source bucket and sending filtered events to the EventBridge rule.
+ Create or use an existing S3 bucket where AWS CloudTrail can store its log files. AWS CloudTrail must have the permissions required to deliver log files to an Amazon S3 bucket. The bucket cannot be configured as a [Requester Pays](https://docs.aws.amazon.com/AmazonS3/latest/dev/RequesterPaysBuckets.html) bucket. When you create an Amazon S3 bucket as part of creating or updating a trail in the console, AWS CloudTrail attaches the required permissions to a bucket for you. For more information, see [Amazon S3 Bucket Policy for CloudTrail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-s3-bucket-policy-for-cloudtrail.html).

# Create an EventBridge rule for an Amazon S3 source (console)
<a name="create-cloudtrail-S3-source-console"></a>

Before you set up a rule in EventBridge, you must create an AWS CloudTrail trail. For more information, see [Creating a Trail in the Console](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-a-trail-using-the-console-first-time.html).

**Important**  
If you use the console to create or edit your pipeline, your EventBridge rule and AWS CloudTrail trail are created for you.

**To create a trail**

1. Open the AWS CloudTrail console.

1. In the navigation pane, choose **Trails**.

1. Choose **Create trail**. For **Trail name**, enter a name for your trail.

1. Under **Storage location**, create or specify the bucket to be used to store the log files. By default, Amazon S3 buckets and objects are private. Only the resource owner (the AWS account that created the bucket) can access the bucket and its objects. The bucket must have a resource policy that allows AWS CloudTrail permissions to access the objects in the bucket.

1. Under **Trail log bucket and folder**, specify an Amazon S3 bucket and the object prefix (folder name) to log data events for all objects in the folder. For each trail, you can add up to 250 Amazon S3 objects. Complete the required encryption key information and choose **Next**.

1. For **Event type**, choose **Management events**.

1. For **Management events**, choose **Write**. The trail records Amazon S3 object-level API activity (for example, `GetObject` and `PutObject`) on the specified bucket and prefix.

1. Choose **Write**. 

1. If you're satisfied with the trail, choose **Create trail**.

**To create an EventBridge rule that targets your pipeline with an Amazon S3 source**

1. Open the Amazon EventBridge console at [https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/).

1. In the navigation pane, choose **Rules**. Leave the default bus selected or choose an event bus. Choose **Create rule**.

1. In **Name**, enter a name for your rule.

1. Under **Rule type**, choose **Rule with an event pattern**. Choose **Next**.

1. Under **Event source**, choose **AWS events or EventBridge partner events**.

1. Under **Sample event type**, choose **AWS events**.

1. In **Sample events**, type S3 as the keyword to filter on. Choose **AWS API call via CloudTrail**.

1. Under **Creation method**, choose **Customer pattern (JSON editor)**.

   Paste the event pattern provided below. Make sure to add the bucket name and S3 object key (or key name) which uniquely identifies the object in the bucket as `requestParameters`. In this example, a rule is created for a bucket named `amzn-s3-demo-source-bucket` and an object key of `my-files.zip`. When you use the **Edit** window to specify resources, your rule is updated to use a custom event pattern.

   The following is a sample event pattern to copy and paste:

   ```
   {
       "source": [
           "aws.s3"
       ],
       "detail-type": [
           "AWS API Call via CloudTrail"
       ],
       "detail": {
           "eventSource": [
               "s3.amazonaws.com"
           ],
           "eventName": [
               "CopyObject",
               "CompleteMultipartUpload",
               "PutObject"
           ],
           "requestParameters": {
               "bucketName": [
                   "amzn-s3-demo-source-bucket"
               ],
               "key": [
                   "my-files.zip"
               ]
           }
       }
   }
   ```

1. Choose **Next**.

1. In **Target types**, choose **AWS service**.

1. In **Select a target**, choose **CodePipeline**. In **Pipeline ARN**, enter the pipeline ARN for the pipeline to be started by this rule.
**Note**  
To get the pipeline ARN, run the **get-pipeline** command. The pipeline ARN appears in the output. It is constructed in this format:   
arn:aws:codepipeline:*region*:*account*:*pipeline-name*  
Sample pipeline ARN:  
arn:aws:codepipeline:us-east-2:80398EXAMPLE:MyFirstPipeline 

1. To create or specify an IAM service role that grants EventBridge permissions to invoke the target associated with your EventBridge rule (in this case, the target is CodePipeline): 
   + Choose **Create a new role for this specific resource** to create a service role that gives EventBridge permissions to your start your pipeline executions.
   + Choose **Use existing role** to enter a service role that gives EventBridge permissions to your start your pipeline executions.

1. (Optional) To specify source overrides with a specific image ID, use the input transformer to pass the data as a JSON parameters. You can also use the input transformer to pass pipeline variables.
   + Expand **Additional settings**.

     Under **Configure target input**, choose **Configure input transformer**.

     In the dialog window, choose **Enter my own**. In the **Input path** box, type the following key-value pairs.

     ```
     {"revisionValue": "$.detail.object.version-id"}
     ```
   + In the **Template** box, type the following key-value pairs.

     ```
                                     
                                     {
         "sourceRevisions": [
             {
                 "actionName": "Source",
                 "revisionType": "S3_OBJECT_VERSION_ID",
                 "revisionValue": "<revisionValue>"
             }
         ],
          "variables": [
             {
                 "name": "Variable_Name",
                 "value": "Variable_Value"
             }
         ]
     }
     ```
   + Choose **Confirm**.

1. Choose **Next**.

1. On the **Tags** page, choose **Next**.

1. On the **Review and create** page, review the rule configuration. If you're satisfied with the rule, choose **Create rule**.

# Create an EventBridge rule for an Amazon S3 source (CLI)
<a name="create-cloudtrail-S3-source-cli"></a><a name="proc-cli-event-s3-createtrail"></a>

**To create an AWS CloudTrail trail and enable logging**

To use the AWS CLI to create a trail, call the **create-trail** command, specifying:
+ The trail name.
+ The bucket to which you have already applied the bucket policy for AWS CloudTrail.

For more information, see [Creating a trail with the AWS command line interface](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-and-update-a-trail-by-using-the-aws-cli.html).

1. Call the **create-trail** command and include the `--name` and `--s3-bucket-name` parameters.

   **Why am I making this change?** This creates the CloudTrail trail required for your S3 source bucket.

   The following command uses `--name` and `--s3-bucket-name` to create a trail named `my-trail` and a bucket named `amzn-s3-demo-source-bucket`.

   ```
   aws cloudtrail create-trail --name my-trail --s3-bucket-name amzn-s3-demo-source-bucket
   ```

1. Call the **start-logging** command and include the `--name` parameter.

   **Why am I making this change? ** This command starts the CloudTrail logging for your source bucket and sends events to EventBridge.

   Example:

   The following command uses `--name` to start logging on a trail named `my-trail`.

   ```
   aws cloudtrail start-logging --name my-trail
   ```

1. Call the **put-event-selectors** command and include the `--trail-name` and `--event-selectors` parameters. Use event selectors to specify that you want your trail to log data events for your source bucket and send the events to the EventBridge rule.

   **Why am I making this change? ** This command filters events.

   Example:

   The following command uses `--trail-name` and `--event-selectors` to specify data events for a source bucket and prefix named `amzn-s3-demo-source-bucket/myFolder`.

   ```
   aws cloudtrail put-event-selectors --trail-name my-trail --event-selectors '[{ "ReadWriteType": "WriteOnly", "IncludeManagementEvents":false, "DataResources": [{ "Type": "AWS::S3::Object", "Values": ["arn:aws:s3:::amzn-s3-demo-source-bucket/myFolder/file.zip"] }] }]'
   ```<a name="proc-cli-event-s3-createrule"></a>

**To create an EventBridge rule with Amazon S3 as the event source and CodePipeline as the target and apply the permissions policy**

1. Grant permissions for EventBridge to use CodePipeline to invoke the rule. For more information, see [Using resource-based policies for Amazon EventBridge](http://docs.aws.amazon.com/eventbridge/latest/userguide/eb-use-resource-based.html).

   1. Use the following sample to create the trust policy to allow EventBridge to assume the service role. Name it `trustpolicyforEB.json`.

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

****  

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

------

   1. Use the following command to create the `Role-for-MyRule` role and attach the trust policy.

      **Why am I making this change?** Adding this trust policy to the role creates permissions for EventBridge.

      ```
      aws iam create-role --role-name Role-for-MyRule --assume-role-policy-document file://trustpolicyforEB.json
      ```

   1. Create the permissions policy JSON, as shown here for the pipeline named `MyFirstPipeline`. Name the permissions policy `permissionspolicyforEB.json`.

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

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "codepipeline:StartPipelineExecution"
                  ],
                  "Resource": [
                      "arn:aws:codepipeline:us-west-2:111122223333:MyFirstPipeline"
                  ]
              }
          ]
      }
      ```

------

   1. Use the following command to attach the new `CodePipeline-Permissions-Policy-for-EB` permissions policy to the `Role-for-MyRule` role you created.

      ```
      aws iam put-role-policy --role-name Role-for-MyRule --policy-name CodePipeline-Permissions-Policy-For-EB --policy-document file://permissionspolicyforEB.json
      ```

1. Call the **put-rule** command and include the `--name`, `--event-pattern`, and `--role-arn` parameters.

   The following sample command creates a rule named `MyS3SourceRule`.

   ```
   aws events put-rule --name "MyS3SourceRule" --event-pattern "{\"source\":[\"aws.s3\"],\"detail-type\":[\"AWS API Call via CloudTrail\"],\"detail\":{\"eventSource\":[\"s3.amazonaws.com\"],\"eventName\":[\"CopyObject\",\"PutObject\",\"CompleteMultipartUpload\"],\"requestParameters\":{\"bucketName\":[\"amzn-s3-demo-source-bucket\"],\"key\":[\"my-key\"]}}}
    --role-arn "arn:aws:iam::ACCOUNT_ID:role/Role-for-MyRule"
   ```

1. To add CodePipeline as a target, call the **put-targets** command and include the `--rule` and `--targets` parameters.

   The following command specifies that for the rule named `MyS3SourceRule`, the target `Id` is composed of the number one, indicating that in a list of targets for the rule, this is target 1. The command also specifies an example `ARN` for the pipeline. The pipeline starts when something changes in the repository.

   ```
   aws events put-targets --rule MyS3SourceRule --targets Id=1,Arn=arn:aws:codepipeline:us-west-2:80398EXAMPLE:TestPipeline
   ```

1. (Optional) To configure an input transformer with source overrides for a specific image ID, use the following JSON in your CLI command. The following example configures an override where:
   + The `actionName`, `Source` in this example, is the dynamic value, defined at pipeline creation, not derived from the source event.
   + The `revisionType`, `S3_OBJECT_VERSION_ID` in this example, is the dynamic value, defined at pipeline creation, not derived from the source event.
   + The `revisionValue`, <*revisionValue*> in this example, is derived from the source event variable.

   ```
   {
       "Rule": "my-rule",
       "Targets": [
           {
               "Id": "MyTargetId",
               "Arn": "ARN",
               "InputTransformer": {
                   "InputPathsMap": {
                       "revisionValue": "$.detail.object.version-id"
                   },
                   "InputTemplate": {
                       "sourceRevisions": {
                           "actionName": "Source",
                           "revisionType": "S3_OBJECT_VERSION_ID",
                           "revisionValue": "<revisionValue>"
                       }
                   }
               }
           }
       ]
   }
   ```<a name="proc-cli-flag-s3"></a>

**To edit your pipeline's PollForSourceChanges parameter**
**Important**  
When you create a pipeline with this method, the `PollForSourceChanges` parameter defaults to true if it is not explicitly set to false. When you add event-based change detection, you must add the parameter to your output and set it to false to disable polling. Otherwise, your pipeline starts twice for a single source change. For details, see [Valid settings for the `PollForSourceChanges` parameter](PollForSourceChanges-defaults.md).

1. Run the **get-pipeline** command to copy the pipeline structure into a JSON file. For example, for a pipeline named `MyFirstPipeline`, run the following command: 

   ```
   aws codepipeline get-pipeline --name MyFirstPipeline >pipeline.json
   ```

   This command returns nothing, but the file you created should appear in the directory where you ran the command.

1. Open the JSON file in any plain-text editor and edit the source stage by changing the `PollForSourceChanges` parameter for a bucket named `amzn-s3-demo-source-bucket` to `false`, as shown in this example.

   **Why am I making this change?** Setting this parameter to `false` turns off periodic checks so you can use event-based change detection only.

   ```
   "configuration": {
       "S3Bucket": "amzn-s3-demo-source-bucket",
       "PollForSourceChanges": "false",
       "S3ObjectKey": "index.zip"
   },
   ```

1. If you are working with the pipeline structure retrieved using the **get-pipeline** command, you must remove the `metadata` lines from the JSON file. Otherwise, the **update-pipeline** command cannot use it. Remove the `"metadata": { }` lines and the `"created"`, `"pipelineARN"`, and `"updated"` fields.

   For example, remove the following lines from the structure:

   ```
   "metadata": {
       "pipelineArn": "arn:aws:codepipeline:region:account-ID:pipeline-name",
       "created": "date",
       "updated": "date"
   },
   ```

   Save the file.

1. To apply your changes, run the **update-pipeline** command, specifying the pipeline JSON file:
**Important**  
Be sure to include `file://` before the file name. It is required in this command.

   ```
   aws codepipeline update-pipeline --cli-input-json file://pipeline.json
   ```

   This command returns the entire structure of the edited pipeline.
**Note**  
The **update-pipeline** command stops the pipeline. If a revision is being run through the pipeline when you run the **update-pipeline** command, that run is stopped. You must manually start the pipeline to run that revision through the updated pipeline. Use the **start-pipeline-execution** command to manually start your pipeline.

# Create an EventBridge rule for an Amazon S3 source (CloudFormation template)
<a name="create-cloudtrail-S3-source-cfn"></a>

To use CloudFormation to create a rule, update your template as shown here.<a name="proc-cfn-event-s3-createrule"></a>

**To create an EventBridge rule with Amazon S3 as the event source and CodePipeline as the target and apply the permissions policy**

1. In the template, under `Resources`, use the `AWS::IAM::Role` CloudFormation resource to configure the IAM role that allows your event to start your pipeline. This entry creates a role that uses two policies:
   + The first policy allows the role to be assumed.
   + The second policy provides permissions to start the pipeline.

   **Why am I making this change?** Adding `AWS::IAM::Role` resource enables CloudFormation to create permissions for EventBridge. This resource is added to your CloudFormation stack.

------
#### [ 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. Use the `AWS::Events::Rule` CloudFormation resource to add an EventBridge rule. This event pattern creates an event that monitors `CopyObject`, `PutObject` and `CompleteMultipartUpload` on your Amazon S3 source bucket. In addition, include a target of your pipeline. When `CopyObject`, `PutObject`, or `CompleteMultipartUpload` occurs, this rule invokes `StartPipelineExecution` on your target pipeline.

   **Why am I making this change?** Adding the `AWS::Events::Rule` resource enables CloudFormation to create the event. This resource is added to your CloudFormation stack.

------
#### [ 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. Add this snippet to your first template to allow cross-stack functionality:

------
#### [ 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. (Optional) To configure an input transformer with source overrides for a specific image ID, use the following YAML snippet. The following example configures an override where:
   + The `actionName`, `Source` in this example, is the dynamic value, defined at pipeline creation, not derived from the source event.
   + The `revisionType`, `S3_OBJECT_VERSION_ID` in this example, is the dynamic value, defined at pipeline creation, not derived from the source event.
   + The `revisionValue`, <*revisionValue*> in this example, is derived from the source event variable.

   ```
   ---
   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. Save your updated template to your local computer, and open the CloudFormation console. 

1. Choose your stack, and then choose **Create Change Set for Current Stack**. 

1. Upload your updated template, and then view the changes listed in CloudFormation. These are the changes that will be made to the stack. You should see your new resources in the list.

1. Choose **Execute**.<a name="proc-cfn-flag-s3"></a>

**To edit your pipeline's PollForSourceChanges parameter**
**Important**  
When you create a pipeline with this method, the `PollForSourceChanges` parameter defaults to true if it is not explicitly set to false. When you add event-based change detection, you must add the parameter to your output and set it to false to disable polling. Otherwise, your pipeline starts twice for a single source change. For details, see [Valid settings for the `PollForSourceChanges` parameter](PollForSourceChanges-defaults.md).
+ In the template, change `PollForSourceChanges` to `false`. If you did not include `PollForSourceChanges` in your pipeline definition, add it and set it to `false`.

  **Why am I making this change?** Changing `PollForSourceChanges` to `false` turns off periodic checks so you can use event-based change detection only.

------
#### [ 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>

**To create a second template for your Amazon S3 pipeline's CloudTrail resources**
+ In a separate template, under `Resources`, use the `AWS::S3::Bucket`, `AWS::S3::BucketPolicy`, and `AWS::CloudTrail::Trail` CloudFormation resources to provide a simple bucket definition and trail for CloudTrail.

  **Why am I making this change? ** Given the current limit of five trails per account, the CloudTrail trail must be created and managed separately. (See [Limits in AWS CloudTrail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/WhatIsCloudTrail-Limits.html).) However, you can include many Amazon S3 buckets on a single trail, so you can create the trail once and then add Amazon S3 buckets for other pipelines as necessary. Paste the following into your second sample template file.

------
#### [ 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
        }
      }
    }
  }
  
  ...
  ```

------